2012-05-13 72 views
1

據我所知,Spring使用JDK爲實現任何推論的類生成動態代理,同時使用Cglib爲不實現任何推論的類生成動態代理。對於decarative transcation,Spring使用代理來添加事務方面。請看下面的代碼:這個註釋是否適用於Spring聲明式事務

interface Demo { 
    void methodA(); 
} 
public class DemoImpl implements Demo{ 
    @Transactional 
    public void updateA() {} 
    @Transactional 
    public void updateB() {} 
} 

我覺得updateA可以很好地處理事務。但是updateB方法呢? @Transactional是否適用於它? 也許我的理解是不正確的。如果提供相關的Spring源代碼來解釋Spring如何使用JDK/cglib來代理類和接口,那就太好了。由於

我對XML的配置:

<tx:annotation-driven transaction-manager="transactionManager" /> 

回答

1

JDK動態代理

在這種情況下,你的bean是包裹着實現Demo接口的代理。從那一刻起,您只能使用該界面。試圖注入或取回豆的DemoImpl類型將導致可怕的Abstract DAO pattern and Spring's "Proxy cannot be cast to ..." problem!

這種類型的答案你的問題 - 你只能訪問updateA(),這是唯一的交易方法。在updateB()附近的註釋被忽略。

但是如果從updateA()調用updateB()是事務性的,因爲它會結合由updateA()啓動(默認事務傳播)的交易。

CGLIB代理

在這種情況下,接口被忽略。 將創建DemoImpl(顯然也實現Demo接口)的子類,並在兩個update*()方法上應用事務行爲。現在如果你注入類型爲DemoImpl的bean(在這種情況下根本不需要接口,並且Impl後綴很醜),你可以安全且事務性地調用這兩種方法。

查看我的文章:Spring pitfalls: proxyingSpring AOP riddle瞭解更多詳情。

+0

謝謝托馬斯。如果我有這個配置,Spring會爲我選擇哪種情況: Jacky

+1

@Jacky:默認情況下,Spring使用JDK代理。如果設置了'proxy-target-class'屬性,它將升級到CGLIB代理,參見:[11.5.6使用@Transactional](http://static.springsource.org/spring/docs/current/spring-framework-reference /html/transaction.html#transaction-declarative-annotations)。 –

相關問題