解決AOP嵌套失效的問題


一、問題起源

我們定義了一個注解如下:

 1 /**
 2  * AOP的切面嵌套測試-注解  3  *  4  * @author suxiaolong  5  */
 6 @Target({ElementType.PARAMETER, ElementType.METHOD})  7 @Retention(RetentionPolicy.RUNTIME)  8 public @interface AnnotationNest {  9 
10     /**
11  * 模塊名稱 12  * 13  * @return 模塊名稱 14      */
15  String moduleName(); 16 
17 }

我們這樣使用它——將注解加到同一個類的多個方法中,這多個方法中存在相到調用:

 1 @Component  2 public class AnnotationNestClass {  3     @AnnotationNest(moduleName = "parent")  4     public void parent(String string) throws Exception {  5         System.out.println("parent-body");  6         this.child(string);  7 }  8 
 9     @AnnotationNest(moduleName = "child") 10     public void child(String string) { 11         System.out.println("child-body"); 12 } 13 }

調用:

 1 @RestController  2 @RequestMapping(value = "/user")  3 public class SignController {  4  @Autowired  5  AnnotationNestClass annotationNestClass;  6 
 7     @GetMapping(value = "/query")  8     public void queryUser() throws Exception{  9         annotationNestClass.parent("parent"); 10  } 11 }

如果是上面的這種調用,那么AnnotationNestClass.child()的切面將不能進入。

 

二、原因

AnnotationNestClass中用this調用的時候,this代表的不再是代理類,而是當前這個類本身,因而切面無法進入。

 

三、解決辦法一:自我注入

 

 通過自我注入,這里就能拿到代理類。 

 

四、解決方法二:通過AopContext.curretnProxy()

 

       這里要注意,AopContxt.currentProxy()方法不能放到多線程中進行獲取,因為AopContext.currentProxy()使用的是LocalThread存儲當前代理,在新的線程中,LocalThread為空,所以就拿不到代理。

       如果想要在多線程環境中獲取當前類的代碼,就在線程外獲取,傳遞給線程去處理,如下所示:

 

 

五、解決方法三:引入一個新的類

 將方法child()放到一個新的類,這種方法就不推薦了。

 

六、參考文章

 1、 https://blog.csdn.net/hl_java/article/details/79445799

2、 https://blog.csdn.net/tjreal/article/details/80714294

3、 https://blog.csdn.net/Liu_York/article/details/86681933

4、 https://www.cnblogs.com/yjmyzz/p/how-to-use-aop-in-multi-thread-spring-application.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM