4月更文d25n25-@aspect切面进行自定义注解拦截并获取注解参数

191 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第25天,点击查看活动详情

@aspect切面进行自定义注解拦截并获取注解参数

前文

本文内容为在开发中有一个需求,需要在若干个请求但不是全部请求中增加一个操作记录,因此采用切面的方式。而为了区分请求,则通过自定义注解进行切面接口标注。同时由于该需求需要进行请求类型的区分,因此选择在注解中增加一个字段,以字段内容进行实际请求的区分。

操作思路

为了解决该问题,我首先进行了自定义注解的设置,将其设置为作用范围为方法,并在其中设置一个字段,用来进行请求类型的标记。随后,在对应的请求入口处进行该注解的使用。

@Documented
@ResponseBody
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ReqSuccessAop {
    String type() default "";
}

下一步,则到了我们的核心问题,如何进行切面的处理。首先根据业务的实际需求,采用@Around注解进行处理。该注解能够获得请求值,并能在请求完成后进行增强调用,满足该需求的实际使用场景。要注意的是,该类需要将其交给spring框架进行管理。

此后,到了关键的步骤,我们需要在切面中设置切点为所有采用了上述自定义注解的方法,使得所有注解的方法能够进入我们的切点。进入切点后,由于需要对于请求的类型进行区分,因此需要在around中增加请求的参数,请求参数指定为我们的注解类型。这里的注解参数如果不进行手动添加,会出现启动参数不匹配,程序启动失败的问题。至此,我们已经能够在切点中得到注解的内容。当需要进行注解内容调用时,只需要在切点中执行reqSuccessAop.type()也就能够直接获得注解中的数据了。至此,该问题解决完毕。

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(cc.crrc.business.annotation.ReqSuccessAop)")
    public void canSaveLog(){

    }

    @Around(value = "canSaveLog() && @annotation(reqSuccessAop)",argNames = "proceedingJoinPoint,reqSuccessAop")
    public void processAround(ProceedingJoinPoint proceedingJoinPoint, ReqSuccessAop reqSuccessAop) throws Exception {
        System.out.println("切点前执行");
        try {
            proceedingJoinPoint.proceed();
        } catch (Exception e) {
            throw e;
        }catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("切点后执行");
    }
}

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。