質問
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">
解決
プロキシのターゲットが少なくとも1つのインターフェースを実装している場合、Springのデフォルトの動作は、ターゲットのすべてのインターフェースを実装するJDKプロキシを作成することです。これは、ターゲットクラスのサブクラスではないことを意味します。ターゲットの動的サブクラスである代わりにCGLIBプロキシの作成を強制することにより、これをオーバーライドできます。
一般的なルールとして、AOPを使用するが、限られた方法でのみインターフェースを使用する場合は、CGLIBを強制する必要があります。そうしないと、コンテナ内に、ロードしたBean実装と同じタイプではない多くのJDKプロキシが存在します。
Cliff Meyersブログを参照: Spring AOP:CGLIBまたはJDK Dynamic Proxies?
他のヒント
それを見つけたら、簡単に修正できました。 SpringDaoはJdbcDaoSupportを継承しなくなり、機能するようになりました。