簡體   English   中英

同一類調用在Spring AOP cglib中無效

[英]Same class invoke NOT effective in Spring AOP cglib

假設我們有以下課程

@Service
class MyClass {

    public void testA() { 
        testB();
     }

    @Transactional
    public void testB() { ... }
}

現在,如果我們調用myClass.testA(); 在測試中,那么testB @Transactional不會生效。 我認為的原因如下。

Cglib將為MyClass創建一個代理bean,如下所示:

Class Cglib$MyClass extends MyClass {

    @Override
    public void testB() {
        // ...do transactional things
        super.testB();
    }
}

現在我們調用myClass.testA() ,它將調用MyClass.testB()而不是Cglib$MyClass.testB() 因此,@ @Transactional無效。 (我對嗎?)

我試圖為兩種方法(即testA()testB() )添加@Transactional 代理類應該這樣。

Class Cglib$MyClass extends MyClass {

    @Override
    public void testA() {
        // ...do transactional things
        super.testA();
    }

    @Override
    public void testB() {
        // ...do transactional things
        super.testB();
    }
}

在這種情況下,盡管我們成功調用了Cglib$MyClass.testA() ,但它仍將移至MyClass.testB()

因此,我的結論是,除非使用AopContext.currentProxy() ,否則同一類中的兩個方法相互調用將使aop注釋無法生效。

我猜對了嗎? 非常感謝您的建議!

眾所周知,Spring AOP由於其基於代理的性質而不能並且不能捕獲諸如this.someMethod(..)類的內部方法調用,這是眾所周知的且有據可查的事實(請搜索“ self-invocation”一詞this.someMethod(..)

因此,正如您所說,您要么需要顯式引用公開的代理對象,要么通過加載時編織從Spring AOP切換到完整的AspectJ

您幾乎是正確的。 代理看起來像這樣:

class Cglib$MyClass extends MyClass {

  MyClass delegate;

  @Override
  public void testB() {
    // ...do transactional things
    delegate.testB();
  }
}

Spring會轉發任何呼叫,這就是為什么您的嵌套注釋未激活的原因。

同樣,如果像testA這樣的虛擬方法被覆蓋,Spring testA避免調用被覆蓋的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM