同じインターフェースを実装する 2 つの Bean を自動配線する - デフォルトの Bean を自動配線に設定するにはどうすればよいでしょうか? 質問する

同じインターフェースを実装する 2 つの Bean を自動配線する - デフォルトの Bean を自動配線に設定するにはどうすればよいでしょうか? 質問する

背景:

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;

おすすめ記事