假设我们有以下课程
@Service
class MyClass {
public void testA() {
testB();
}
@Transactional
public void testB() { ... }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们myClass.testA();
在 test 中调用,那么@Transactional
ontestB
将不会生效。我认为的原因如下。
Cglib 将创建一个代理 bean MyClass
,如下所示:
Class Cglib$MyClass extends MyClass {
@Override
public void testB() {
// ...do transactional things
super.testB();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们调用myClass.testA()
,它将调用MyClass.testB()
而不是Cglib$MyClass.testB()
。所以@Transactional
是无效的。(我对吗?)
我尝试@Transactional
为这两种方法(即testA()
和testB()
)添加。代理类应该是这样的。
Class Cglib$MyClass extends MyClass {
@Override
public void testA() {
// ...do transactional things
super.testA();
}
@Override
public void testB() {
// ...do transactional things
super.testB();
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,虽然我们成功调用了Cglib$MyClass.testA()
,但它仍然会转到MyClass.testB()
。
所以我的结论是,同一个类中的两个方法相互调用会导致aop注解失效,除非我们使用AopContext.currentProxy()
.
我上面的猜测是对的吗?非常感谢您的建议!
你几乎是对的。代理看起来更像这样:
class Cglib$MyClass extends MyClass {
MyClass delegate;
@Override
public void testB() {
// ...do transactional things
delegate.testB();
}
}
Run Code Online (Sandbox Code Playgroud)
任何调用都会由 Spring 转发,这就是您的嵌套注释未激活的原因。
另外,如果像这样的虚方法testA
被重写,Spring 就无法避免调用被重写的方法。
归档时间: |
|
查看次数: |
957 次 |
最近记录: |