Spring?代理?Bean?獲取不到原始?Bean?對象注解解決方法
一、問題描述
在接受 mq 消息的時候,需要做一個重試次數(shù)限制,如果超過 maxNum 就發(fā)郵件告警,不再重試。 所以我需要對 consumer 對象進行代理,然后如果超過異常次數(shù),我直接返回成功,并且發(fā)送成功消息,但是我獲取 consumer handler 方法的方式是通過 method.getAnnotation(XXClient.class) 方式,那么就會返回 null。
1.問題示例代碼
- 目標類, 我這里就之定義一個
test方法,里面做一些個簡單的打印。
@Component
public class TestBean {
@Anno
public void test() {
System.out.println("test .....");
}
}- 代理邏輯邏輯處理, 主要就是做一個
@Around的方法覆蓋,保證在調(diào)用目標方法之前,先輸出我插入的邏輯。
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
String key() default "100%";
}
@Aspect
@Component
public class AnnoAspect {
@Around("@annotation(anno)")
public Object anno(ProceedingJoinPoint point, Anno anno) throws Throwable {
System.out.println("anno invoke!!!!!!");
return point.proceed();
}
}- 調(diào)用點, 通過
AnnotationConfigApplicationContext獲取bean. 然后通過getMethods()獲取所有的方法,最后查找Anno注解的Method對象。
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanStart.class);
TestBean bean = applicationContext.getBean(TestBean.class);
Class<? extends TestBean> classz = bean.getClass();
Method[] methods = classz.getMethods();
for (Method m : methods) {
Anno annotation = m.getAnnotation(Anno.class);
if (annotation != null) {
System.out.println(" ============= invoke test ===========");
m.invoke(bean, new Object());
}
} 由于 m.getAnnotaion(Anno.class) 無法獲取到注解信息,所以執(zhí)行 test 方法失敗, 到此問題還原完畢,我們再來看看如何解決。
二、解決方案
通過 Anno ao = AnnotationUtils.findAnnotation(method, Anno.class); 方法獲取即可。
有的代碼是這樣寫的 :
String name = classz.getName();
boolean isSpringProxy = name.indexOf("SpringCGLIB$$") >= 0;
Method[] methods;
if (isSpringProxy) {
methods = ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(bean));
} else {
methods = classz.getMethods();
}
// 省略部分代碼
if (isSpringProxy) {
annotation = AnnotationUtils.findAnnotation(method, MqClient.class);
} else {
annotation = method.getAnnotation(Anno.class);
}這里他會做一個判斷,如果是代理對象就調(diào)用 ReflectionUtils.getAllDeclaredMethods 獲取所有的方法, 然后再去拿注解的時候二次判斷一下,如果存在代理,那么就通過 AnnotationUtils.findAnnotation 感覺是相當?shù)膰乐敗?/p>
總結(jié):
Spring 提供了非常強大的一站式開發(fā)功能,而且還提供了比較優(yōu)秀的工具方法比如: BeanUtils 、ReflectionUtils 、AnnotationUtils 等,這些都是我們值得掌握的基礎工具類。
相關(guān)文章
SpringBoot實現(xiàn)定時任務的三種方式小結(jié)
這篇文章主要介紹了SpringBoot實現(xiàn)定時任務的三種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
springAOP中用joinpoint獲取切入點方法的參數(shù)操作
這篇文章主要介紹了springAOP中用joinpoint獲取切入點方法的參數(shù)操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Java?DelayQueue實現(xiàn)任務延時示例講解
DelayQueue是一個無界的BlockingQueue的實現(xiàn)類,用于放置實現(xiàn)了Delayed接口的對象,其中的對象只能在其到期時才能從隊列中取走。本文就來利用DelayQueue實現(xiàn)延時任務,感興趣的可以了解一下2022-09-09
Java生成隨機數(shù)之Random與ThreadLocalRandom性能比較詳解
大家項目中如果有生成隨機數(shù)的需求,我想大多都會選擇使用Random來實現(xiàn),它內(nèi)部使用了CAS來實現(xiàn)。?實際上,JDK1.7之后,提供了另外一個生成隨機數(shù)的類ThreadLocalRandom,那么他們二者之間的性能是怎么樣的呢?本文就來詳細說說2022-12-12
SpringBoot配置文件bootstrap和application區(qū)別及說明
這篇文章主要介紹了SpringBoot配置文件bootstrap和application區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
從0構(gòu)建Oauth2Server服務之Refreshing-access-tokens
這篇文章主要為大家介紹了從0構(gòu)建Oauth2Server服務之Refreshing-access-tokens刷新令牌示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05
eclipse創(chuàng)建springboot項目的三種方式總結(jié)
這篇文章主要介紹了eclipse創(chuàng)建springboot項目的三種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
HttpClient實現(xiàn)調(diào)用外部項目接口工具類的示例
下面小編就為大家?guī)硪黄狧ttpClient實現(xiàn)調(diào)用外部項目接口工具類的示例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10

