一、問題起源
我們定義了一個注解如下:
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
