解決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、 http://www.rzrgm.cn/yjmyzz/p/how-to-use-aop-in-multi-thread-spring-application.html

浙公網安備 33010602011771號