SpringAOP获取方法参数上的注解

一、示例

① 如下代码,自定义一个参数注解@Test,并将其使用到方法参数上,用于标注需要检验的参数

/**
* 自定义注解,用于参数
*/
@Target(PARAMETER)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{
}
/**
* 接口层,使用使用@Test注解标记参数
*/
@RestController
@RequestMapping("/v1/test")
public class TestController {
    @PostMapping(value = "/email", produces = "application/json")
    public String send(@RequestBody @Test MailSendDTO mailSendDTO) {
        //TODO 业务处理
        return "SUCCESS";
    }
}

② 通过切面拦截该方法,从连接点获取signature,并将signature强转为MethodSignature,从而从MethodSignature对象可以获取拦截的方法对象以及方法参数注解

@Aspect
@Configuration
public class ValidateAop {

    /**
     * 切点配置,表达式, 在com.laoxi.test.controller包下,所有的类public的任意参数的方法
     */
    @Pointcut("execution(public * com.laoxi.test.controller.*.*(..))")
    public void validate(){}

    @Before("validate()")
    public void doBefore(JoinPoint joinPoint){
        Object[] params = joinPoint.getArgs();
        if(params.length == 0){
            return;
        }
        //获取方法,此处可将signature强转为MethodSignature
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        //参数注解,1维是参数,2维是注解
        Annotation[][] annotations = method.getParameterAnnotations();
        for (int i = 0; i < annotations.length; i++) {
            Object param = params[i];
            Annotation[] paramAnn = annotations[i];
            //参数为空,直接下一个参数
            if(param == null || paramAnn.length == 0){
                continue;
            }
            for (Annotation annotation : paramAnn) {
                //这里判断当前注解是否为Test.class
                if(annotation.annotationType().equals(Test.class)){
                    //校验该参数,验证一次退出该注解
                    //TODO 校验参数
                    break;
                }
            }
        }
    }
}

 二、debug

通过debug代码:

可发现连接点实际为MethodInvocationProceedingJoinPoint对象,连接点中的signature则为MethodSignatureImpl对象,是MethodInvocationProceedingJoinPoint的内部类。

SpringAOP获取方法参数上的注解_第1张图片

三、类图及源码

MethodInvocationProceedingJoinPoint类图,顶级实现了JoinPoint(以后再使用切面的时候,可以看看其他类里面都扩展了哪些方法可以直接使用)

SpringAOP获取方法参数上的注解_第2张图片

MethodSignatureImpl类图,顶级实现了Signature(以后再使用切面的时候,可以看看其他类里面都扩展了哪些方法可以直接使用)

SpringAOP获取方法参数上的注解_第3张图片

 

你可能感兴趣的:(技术问题探索,java,AOP,spring)