春は@Configurationクラスで成功した切片内クラスの関数呼び出しは、なぜそれが通常の豆でそれをサポートしていないことができれば?

ゴネンI:

私は最近、春が正常@Configurationクラスではなく、通常のBean内のイントラクラスの関数呼び出しをインターセプトすることに気づきました。

このような呼び出し

@Repository
public class CustomerDAO {  
    @Transactional(value=TxType.REQUIRED)
    public void saveCustomer() {
        // some DB stuff here...
        saveCustomer2();
    }
    @Transactional(value=TxType.REQUIRES_NEW)
    public void saveCustomer2() {
        // more DB stuff here
    }
}

saveCustomer()CustomerDAOプロキシで実行される、saveCustomer2のコード()のコードは開封されたCustomerDAOクラスで実行されますながらので、私は、デバッガで「この」を見て、見ることができるように、新しいトランザクションを開始するために失敗し、そう春はsaveCustomer2への呼び出しをインターセプトする機会を持っていません。

しかし、トランザクションマネージャーは、()()createDataSourceを呼び出したときに、次の例では、それが正しく傍受され、デバッガで「この」を見ることで明らかなように、ではない開封されたクラスで、プロキシのcreateDataSource()を呼び出します。

@Configuration
public class PersistenceJPAConfig {
    @Bean
    public DriverManagerDataSource createDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        //dataSource.set ... DB stuff here
        return dataSource;
    }

   @Bean 
       public PlatformTransactionManager transactionManager(   ){
           DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(createDataSource());
           return transactionManager;
       }
}

私の質問があるので、なぜではなく、最初に、第二の例では内、クラスの関数呼び出しをインターセプト正しく春することができます。それは、動的プロキシの種類を使用していますか?

編集: 私は今、次のことを理解し、ここでの回答や他のソースから:@Transactionalは、Proxyパターンがユーザクラスのラッピング/組成によって行われる春AOPを使用して実装されます。AOPプロキシは、その多くの側面が一緒に連鎖させることができ、かつCGLIBプロキシまたはJavaの動的プロキシかもしれので、一般的な十分です。

@Configurationクラスでは、春にはまた、この場合には、そのようなチェックなど、ユーザーの/スーパー関数を呼び出す前に、いくつかの余分な作業を行うもので、ユーザーの@Bean機能をオーバーライドするユーザー@Configurationクラスから継承し、強化されたクラスを作成するためにCGLIBを使用しています機能かどうかの最初の呼び出しです。このクラスは、プロキシか?これは、定義に依存します。あなたはそれが組成物を用いて、それをラップするのではなく、実際のオブジェクトからの継承を使用するプロキシであることを言うかもしれません。

私は理解してここに与えられた答えから、要約すると、これら2つの全く異なるメカニズムがあります。これらの設計上の選択が行われたのはなぜ別の、未解決の問題です。

智異Tousek:

AOPプロキシおよびので@Configurationクラスは、異なる目的を果たす、と大幅に異なった方法(両方がプロキシを使用することを含むにもかかわらず)に実装されています。 @Configurationは継承を使用しながら、基本的には、AOPは、組成物を使用しています

AOPプロキシ

方法は、これらの作業は、彼らが後/前に、関連するアドバイスのロジックを行うプロキシ作成することを基本的に委譲元(プロキシ)オブジェクトへの呼び出しを。すべての依存関係は、このプロキシとすべてのコールに設定されているので、容器は、このプロキシ代わりにプロキシオブジェクト自体を登録別の豆から、このプロキシを経由。しかし、プロキシになるオブジェクト自体は、プロキシへのポインタを(それが唯一のプロキシがターゲットオブジェクトへのポインタを持っている、プロキシだ知っていません)がありません。だから、他の方法と、そのオブジェクト内のすべての呼び出しは、プロキシを経由しません。

(私はあなたがこの部分の正しい理解を持っているように見えることから、@Configurationとの対比のためにここにこれを追加しています。)

@Configuration

今、あなたは通常、AOPプロキシを適用することをオブジェクトながらに、アプリケーションの標準の一部であり、@Configurationクラスが違う- 1のために、あなたはおそらく、直接自分でそのクラスのインスタンスを作成するつもりはありません。このクラスは、本当に、Beanコンテナの書き込み構成にだけの方法である春の外では意味を持たない、あなたは知っている、それは特別な方法で春で使用されること、それが外単なるJavaコードのいくつかの特別な意味を持っていること-などをその@Bean-annotatedの方法は、実際のSpring Beanを定義します。

このため、春は(あなたが唯一の春のために、このクラスを提供することを知っている、とあなたはそのを作成したり、使用しない、覚えて、それはあなたのコードで何かを破るだろうという気にせずに、このクラスにはるかに過激なことを行うことができます直接インスタンス)。

何それは実際に行うことは、それはだ、プロキシ作成しているのサブクラス@Configurationクラスをこのように、それはすべての(非の呼び出しインターセプトすることができfinal、非privateの)メソッド@Configurationのクラスも同じオブジェクト内(メソッドが効果的にすべてのプロキシによってオーバーライド、およびJava仮想すべてのメソッドを有しているために)。プロキシは、正確にこれは(意味的に)代わりに、スーパークラスのメソッドを呼び出すの実際のBeanインスタンスへのSpring Beanへの参照であることを認識する任意のメソッド呼び出しをリダイレクトしません。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=122273&siteId=1