场景:
在项目中定义了一个注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NeedXXXCheck {
CheckItemEnum[] value();
enum CheckItemEnum {
CHENCK_XXX_STATUS
}
}
使用AOP 定义一个切面,对使用了该注解的方法进行特定的参数校验
@Component
@Aspect
@Slf4j
public class InnerFacadeValidationXXX {
@Around(value = "execution(* com.XXX.facade..*.*(..))")
public Object checkXXXAround(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
NeedXXXCheck annotation = method.getAnnotation(NeedXXXCheck.class);
if (annotation == null) {
return joinPoint.proceed();
}
Object[] args = joinPoint.getArgs();
// 进行参数校验
...
}
然而在发现在实际方法调用过程中发现,使用@NeedXXXCheck 注解的方法,并没有进行参数校验。
在本地环境中对此进行debug,method.getAnnotation(NeedXXXCheck .class)获取到的annotation 是null,所以就直接进行了目标方法的执行,即进行joinPoint.proceed这个方法。
再继续debug发现,在获取method的时候不对劲了
就在spring的配置中
<aop:aspectj-autoproxy proxy-target-class='false'/>
在spring中配置使用了jdk代理,而在项目中注解是使用在接口的实现类上,当AOP获取到切入点是接口,没有取到对应的注解,导致method.getAnnotation获取到的为null
把配置改成
<aop:aspectj-autoproxy proxy-target-class='true'/>
这时使用了cglib代理,便可以成功的获取到对应切入点的注解