背景:
Spring 2.5/Java/Tomcat アプリケーションがあります。次の Bean は、アプリケーション全体のさまざまな場所で使用されています。
public class HibernateDeviceDao implements DeviceDao
そして、次の Bean は新しいものです。
public class JdbcDeviceDao implements DeviceDao
最初のBeanは次のように構成されます(パッケージ内のすべてのBeanが含まれます)
<context:component-scan base-package="com.initech.service.dao.hibernate" />
2番目の(新しい)Beanは別々に設定されます
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
これにより、当然ながら、サーバーの起動時に例外が発生します。
ネストされた例外は org.springframework.beans.factory.NoSuchBeanDefinitionException です: タイプ [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao] の一意の Bean が定義されていません: 一致する Bean が 1 つだけあると予想されましたが、2 つ見つかりました: [deviceDao、jdbcDeviceDao]
このようにBeanを自動配線しようとするクラスから
@Autowired
private DeviceDao hibernateDevicDao;
同じインターフェースを実装する Bean が 2 つあるためです。
質問:
Beansを次のように設定することは可能ですか?
1.HibernateDeviceDao
すでに自動配線されている既存のクラスに変更を加える必要はありません。
2.2 番目の (新しい) Bean を次のように使用できます。
@Autowired
@Qualifier("jdbcDeviceDao")
HibernateDeviceDao
つまり、 Bean をデフォルトの Bean として自動接続されるように構成し、同時にアノテーションJdbcDeviceDao
で明示的に指定した場合にの使用を許可する方法が必要になります@Qualifier
。
すでに試したこと:
プロパティを設定してみました
autowire-candidate="false"
JdbcDeviceDao の Bean 構成:
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
<property name="dataSource" ref="jdbcDataSource"/>
</bean>
Springのドキュメントにはこう書いてある
別の Bean の自動配線要件を満たす一致する候補を探すときに、この Bean を考慮する必要があるかどうかを示します。これは名前による明示的な参照には影響しないことに注意してください。名前による明示的な参照は、指定された Bean が autowire 候補としてマークされていない場合でも解決されます。*
JdbcDeviceDao
これは、アノテーションを使用してautowire を使用し@Qualifier
、 をデフォルトの Bean として使用できることを意味すると解釈しましたHibernateDeviceDao
。しかし、どうやら私の解釈は正しくなかったようで、サーバーの起動時に次のエラー メッセージが表示されます。
タイプ [クラス com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao] の依存関係が満たされていません: 一致する Bean が少なくとも 1 つ必要です
修飾子を使用して Bean を自動配線しようとしたクラスから来ています:
@Autowired
@Qualifier("jdbcDeviceDao")
解決:
スカフマンの 提案@Resource アノテーションが機能することを試す。そのため、構成では jdbcDeviceDao の autowire-candidate が false に設定されており、jdbcDeviceDao を使用するときは、@Qualifier ではなく @Resource アノテーションを使用して参照します。
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;
ベストアンサー1
Hibernate DAOクラスを次のようにマークすることをお勧めします。@Primary
つまり(@Repository
で を使用したと仮定HibernateDeviceDao
):
@Primary
@Repository
public class HibernateDeviceDao implements DeviceDao
autowire-candidate
この方法では、他の Bean で選択する必要はなく、デフォルトの autowire 候補として選択されます。
また、 を使用するよりも、特定の豆を選択するために@Autowired @Qualifier
を使用する方がエレガントだと思います。@Resource
@Resource(name="jdbcDeviceDao")
DeviceDao deviceDao;