3

2つのSpringプロキシを設定しています。

  <bean id="simpleBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <ref local="simpleBeanTarget"/>
    </property>
    <property name="interceptorNames">
        <list>
            <value>cacheInterceptor</value>
        </list>
    </property>
</bean>   



 <bean id="springDao" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="springDaoTarget"/>
        <property name="interceptorNames">
            <list>
                <value>daoInterceptor</value>
            </list>
        </property>

    </bean>

simpleBeanは問題なく動作します-springDaoは動作しません。

SpringDaoクラスは次のようになります。

public class SpringDao extends JdbcDaoSupport {

private SimpleJdbcTemplate simpleJdbcTemplate;

public SimpleJdbcTemplate getSimpleJdbcTemplate() {

    if (simpleJdbcTemplate==null) {
        simpleJdbcTemplate= new SimpleJdbcTemplate(getDataSource());
    }
    return simpleJdbcTemplate;
}
    ...

そして、私は私のユニットテストを次のように自動配線しています:

@Autowired
@Qualifier("springDao")
protected SpringDao springDao;

そして、何かが間違っているという最初の兆候は、私がこのエラーを受け取ることです:

フィールドを自動配線できませんでした:。。。ネストされた例外はjava.lang.IllegalArgumentExceptionです

@Qualifierアノテーションをコメントアウトして、単体テストを再度実行すると、次のようになります。

タイプの一意のBeanはありません...単一の一致するBeanが必要ですが、2が見つかりました:[springDaoTarget、springDao]

それが私が期待したことです。

そこで、自動配線をに変更しました

@Autowired
@Qualifier("springDaoTarget")
protected SpringCustomerCapacityDao springDao;

そして、私のユニットテストに以下を追加しました:

        Object proxy = applicationContext.getBean("springDao");

    Assert.assertNotNull(proxy);
    Assert.assertTrue(proxy instanceof SpringDao);

そして、instanceofテストが失敗しました。これは、(私にとって)私のプロキシが実際には私のプロキシではないことを意味します。

だから私は混乱しています。どうしたの?どうすればこれを修正できますか?

編集 これが要求されたspringDaoTarget定義であり、多くの人を失望させます。

<bean id="springDaoTarget" class="com.company.SpringDao">

4

2 に答える 2

9

プロキシのターゲットが少なくとも 1 つのインターフェースを実装する場合、Spring のデフォルトの動作は、ターゲットのすべてのインターフェースを実装する JDK プロキシを作成することです。つまり、対象クラスのサブクラスにはなりません。代わりに、ターゲットの動的サブクラスである CGLIB プロキシの作成を強制することで、これをオーバーライドできます。

原則として、AOP を使用するがインターフェイスを制限された方法でのみ使用する場合は、CGLIB を強制する必要があります。そうしないと、ロードした Bean 実装と同じタイプではない多数の JDK プロキシがコンテナー内に存在することになります。

Cliff Meyers ブログ: Spring AOP: CGLIB or JDK Dynamic Proxies?を参照してください。

于 2008-11-29T07:28:58.243 に答える
1

それを理解したら、修正するのは簡単でした。SpringDao は JdbcDaoSupport を継承しなくなり、動作するようになりました。

于 2008-11-24T16:51:54.597 に答える