Java擷取CGLIB代理類上的注解為null的問題
- 一、場景
- 二、原因分析
- 三、解決方案
- 四、廣告
一、場景
搭建架構的時候踩到的一個坑。spring boot項目,項目中用到了AOP記錄Log,又用到了攔截器判斷權限和記錄系統log到表中,于是在攔截器中需要
HandlerMethod handlerMethod = (HandlerMethod) handler;
擷取類注解和方法注解,但是擷取的類注解是null,源碼如下:
// 擷取類注解
Class<? extends Object> clazz = handlerMethod.getBean().getClass();
CategoryLog categoryLog = AnnotationUtils.findAnnotation(clazz, CategoryLog.class);
if (Objects.isNull(categoryLog)) {
return;
}
String menu = categoryLog.menu();
// 擷取方法注解
Method method = handlerMethod.getMethod();
DescLog descLog = method.getAnnotation(DescLog.class);
if (Objects.isNull(descLog)) {
return;
}
二、原因分析
是由于上述代碼我們所需要擷取的類首先被AOP攔截生成了代理對象。我是debug發現clazz對象是個代理對象可知的,如下圖。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0gDO5QTMwETMwETNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
上圖可知,是cglib代理後的對象(預設是jdk的,我在application.yml裡手動指定的cglib),那麼我們擷取代理對象的注解資訊肯定是擷取不到的,需要擷取原始對象才能拿到注解等資訊。
三、解決方案
通過
org.springframework.core.annotation.AnnotationUtils
注解提供的
findAnnotation
方法即可完美解決問題,代碼在上面已經給到了。用
clazz.getAnnotation(CategoryLog.class);
這種方式是擷取不到的,擷取的是代理對象的,為null。
四、廣告
QQ群:458430385
微信公衆号