現象
:當類的方法使用Spring事務註解@Transactional後,再使用isAnnotationPresent(Class)判斷類方法是否包含註解時,會一直返回false,無法正確獲取類方法註解。
測試代碼
方法註解@JobHandler
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface JobHandler {
String value();
}
類註解@JobWorker
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Component
public @interface JobWorker {
}
第一種情況
:不使用Spring的事務註解@Transactional,可以正確的拿到方法的註解,測試類如下
@JobWorker
public class HelloAnnotation {
@JobHandler("sayHello")
public void sayHello() {
System.out.println("hello annotation");
}
// @Transactional
public void insert() {
System.out.println("插入成功");
}
}
測試方法
@Test
public void testIsAnnotationPresent() {
Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(JobWorker.class);
for (Object serviceBean : serviceBeanMap.values()) {
System.out.println(">>>>>>>> 標記了@JobWorker註解的類" + serviceBean.getClass());
Method[] methods = serviceBean.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(JobHandler.class)) {
System.out.println(">>>>>>>> " + method.getName() + "包含註解@JobHandler");
} else {
System.out.println(">>>>>>>> " + method.getName() + "不包含註解@JobHandler");
}
}
}
}
測試結果:可以看到正確判斷方法是否包含的註解,特別注意的是獲取到標記了@JobWorker註解的類是class com.demo.mybatis.anno.HelloAnnotation
>>>>>>>> 標記了@JobWorker註解的類class com.demo.mybatis.anno.HelloAnnotation
>>>>>>>> insert不包含註解@JobHandler
>>>>>>>> sayHello包含註解@JobHandler
第二種情況
:使用Spring的事務註解@Transactional,isAnnotationPresent(Class)就無法正確的拿到方法的註解了,測試類如下
@JobWorker
public class HelloAnnotation {
@JobHandler("sayHello")
public void sayHello() {
System.out.println("hello annotation");
}
@Transactional
public void insert() {
System.out.println("插入成功");
}
}
測試結果,可以看到HelloAnnotation類被Spring生成的代理類包含了。造成了無法正確獲得方法註解。原因是這個類在事務管理時,被當成了類代理。根據class反射拿到的是代理類,所以拿不到對應的註解。
>>>>>>>> 標記了@JobWorker註解的類class com.demo.mybatis.anno.HelloAnnotation$$EnhancerBySpringCGLIB$$718f198e
>>>>>>>> insert不包含註解@JobHandler
>>>>>>>> sayHello不包含註解@JobHandler
>>>>>>>> CGLIB$sayHello$1不包含註解@JobHandler
>>>>>>>> CGLIB$insert$0不包含註解@JobHandler