我有一个给定的 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()
有几种方法可以解决这个问题:
到目前为止,最好的方法是以以下方式更改您的设计:
methodA() 根本不调用 methodB()
methodA() 和 methodB() 位于不同的 benas 中,其中一个被注入(inject)到另一个中
methodA() 周围的代理逻辑足以满足这两种方法
如果不可能,您的选择是使用 AspectJ 编译(请参阅 Spring AOP or full AspectJ 、 Using AspectJ with Spring applications )。这样您就不再使用代理,但各个方面都融入到您的类中。
或者通过让 bean 对象了解其周围的代理来违反 AOP 原则:
public void methodA(){ ((MyInterface)AopContext.currentProxy()).methodB(); }
关于java - AOP切入点未注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5110803/