一、问题背景
开发程序的时候使用了aop去代理对象,然后其他地方会获取到这个代理对象并获取上面的方法注解和参数注解,运行时却发现无法获取注解,最终折腾一番终于解决。
二、问题原因
Spring项目中若开启CGLIB代理 spring.aop.proxy-target-class=true
注入接口后无法获取其实现类上注解。
通过debug得到class文件名含有EnhancerBySpringCGLIB:使用了AOP去进行代理,由于代理的对象不是接口,代理对象是由cglib代理的。
三、解决方案
正常情况获取注解方式:
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
因此决定换个思路,直接获取cglib代理类的原始对象,获取原始对象上的参数注解就可以了
那我们的解决方式是加一个判断,如果是CGLIB代理类,则通过它的父类去获取方法的参数注解。
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
if(method.getDeclaringClass().getName().contains("$$")) {
try {
parameterAnnotations = method.getDeclaringClass().getSuperclass().getDeclaredMethod(method.getName(), method.getParameterTypes()).getParameterAnnotations();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
注:刚开始网上有解决方案是:
1.将spring.aop.proxy-target-class=true 去掉, 自动使用JDK代理。
2.使用注解解析器工具
import org.springframework.core.annotation.AnnotationUtils;
public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
return findAnnotation(clazz, annotationType, true);
}
这种方式,小伙伴们也可以去尝试一下,但是我用的springboot框架,我的项目内还是需要用到spring的aop动态代理的。