java - AOP切入点未注册

标签 java spring aop

我有一个给定的 spring bean,有 3 个方法,A、B 和 C。methodA 是入口点,它调用 methodB,而该方法调用 methodC。

这是我的 bean :

<bean id="myBean" class="misc.zombies.Braainns" scope="prototype">

这是我的 Java 类,它在其中运行:

@Autowired
private Braainns myBean;

    ...

    myBean.methodA() //remember, methodA -> methodB -> methodC

此切点不起作用,建议从未应用

<aop:config>
    <aop:aspect id="deadLockRetry" ref="myDeadLockRetryExecutor">
        <aop:pointcut id="myRetryOperation" expression="execution(* misc.zombies.Braaainns.methodC(..))"/>
        <aop:around pointcut-ref="myRetryOperation" method="retry"/>    
    </aop:aspect>
</aop:config>

这个切点确实有效,但建议仅适用于方法A

<aop:config>
    <aop:aspect id="deadLockRetry" ref="myDeadLockRetryExecutor">
        <aop:pointcut id="myRetryOperation" expression="execution(* misc.zombies.Braaainns.*(..))"/>
        <aop:around pointcut-ref="myRetryOperation" method="retry"/>    
    </aop:aspect>
</aop:config>

最佳答案

Spring AOP 在您的 bean 周围创建代理,因此对于每个方法 methoda、methodb、methodc,在您的 bean 周围的代理上都存在一个方法 methoda2、methodb2、methodc2。

现在你从外部调用bean.methodA(),客户端实际看到的是代理,所以调用了proxy.methodsA2(),它代理了到 bean.methodA()。现在,如果 bean.methodA() 调用 bean.methodB(),则永远不会调用代理逻辑,因为上下文已经位于代理内部:

proxy             bean  
methodA2() -->    methodA()
                   |
                   V  
methodB2() -->    methodB()

但这就是你想要的:

proxy             bean  
methodA2() -->    methodA()
                     |
   /-----------------/
   |                 
   V
methodB2() -->    methodB()

有几种方法可以解决这个问题:

  1. 到目前为止,最好的方法是以以下方式更改您的设计:

    • methodA() 根本不调用 methodB()

    • methodA() 和 methodB() 位于不同的 benas 中,其中一个被注入(inject)到另一个中

    • methodA() 周围的代理逻辑足以满足这两种方法

  2. 如果不可能,您的选择是使用 AspectJ 编译(请参阅 Spring AOP or full AspectJUsing AspectJ with Spring applications )。这样您就不再使用代理,但各个方面都融入到您的类中。

  3. 或者通过让 bean 对象了解其周围的代理来违反 AOP 原则:

    public void methodA(){
        ((MyInterface)AopContext.currentProxy()).methodB();
    }
    

关于java - AOP切入点未注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5110803/

相关文章:

aop - 面向方面编程中的连接点

java - JUnit 编织错误的 Spring AOP Bean

java - JVM 优化会破坏我的代码吗?

带有 Tomcat 数据库池和 Oracle 的 Spring Boot,没有及时将连接返回到池

java - spring-mvc (portlet) : how to return a pdf file in open file dialog?

java - Spring Tomcat 启动问题 setCatalinaBase(Ljava/io/File;)

c# - 获取有关 Ninject 拦截的方法的信息

java-connector.so 找不到

java - Quickblox 登录无法使用 3.3.1 sdk

Java rowAtPoint() 未返回正确的值