zoukankan      html  css  js  c++  java
  • 解决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

  • 相关阅读:
    sqoop
    HBase API操作
    Hbase 01-安装| shell操作
    Azkaban
    Kafka-API
    Oozie
    Kafka Manager| KafkaMonitor
    kafka工作流程| 命令行操作
    CDH| HUE的自动化安装部署
    Impala
  • 原文地址:https://www.cnblogs.com/gudi/p/12818500.html
Copyright © 2011-2022 走看看