解决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