1

私の知る限り、Spring は JDK を使用してインターフェイスを実装するクラスの動的プロキシを生成し、Cglib を使用してインターフェイスを実装しないクラスの動的プロキシを生成します。宣言型トランザクションの場合、Spring はプロキシを使用してトランザクションの側面を追加します。以下のコードを見てください。

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

updateA はトランザクションでうまく機能すると思います。しかし、updateB メソッドはどうでしょうか。@Transactional はそれに対して機能しますか? 多分私の理解は正しくありません。Spring が JDK/cglib を使用してクラスとインターフェースをプロキシする方法を説明するために、関連する Spring ソース コードが提供されていると便利です。ありがとう

私はxmlに設定を持っています:

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

1 に答える 1

1

JDK 動的プロキシ

この場合、Bean はプロキシ実装Demoインターフェースでラップされます。その瞬間から、そのインターフェイスのみを使用できます。タイプの Bean をインジェクトまたはフェッチしようとするとDemoImpl、恐ろしい抽象 DAO パターンと Spring の「プロキシを ... にキャストできません」という問題が発生します。

この種の質問への回答 - アクセスのみ可能updateA()で、これが唯一のトランザクション方法です。周囲の注釈updateB()は無視されます。

ただし、(デフォルトのトランザクション伝播で)によって開始されたトランザクションにバインドされるため、それから呼び出すupdateB()とトランザクションになります。updateA()updateA()

CGLIB プロキシ

この場合、インターフェイスは無視されます。DemoImplは(明らかにインターフェイスも実装する)のサブクラスを作成し、両方のメソッドDemoにトランザクション動作を適用します。update*()タイプの Bean を注入するとDemoImpl(この場合、インターフェイスはまったく必要なく、Impl接尾辞は醜いです)、両方のメソッドを安全かつトランザクション的に呼び出すことができます。

詳細については、私の記事「Spring の落とし穴: プロキシSpring AOP のなぞなぞ」を参照してください。

于 2012-05-13T08:33:37.097 に答える