我有一个 Spring 2.5/Java/Tomcat 应用程序
public class HibernateDeviceDao implements DeviceDao
以及下面这颗新的豆子:
public class JdbcDeviceDao implements DeviceDao
第一个 bean 是这样配置的(包中的所有 bean 都包含在内)
<context:component-scan base-package="com.initech.service.dao.hibernate" />
第二个(新的) bean 是单独配置的
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
这(当然)导致在启动服务器时出现异常:
嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinition itionException: 没有类型为[ com.sevenp.mobile.samplemgmt.service.Dao 的唯一 bean。DeviceDao ]被定义为: 预期的单个匹配 bean,但找到了2: [ deviceDao,jdbcDeviceDao ]
来自一个试图像这样自动装配豆子的类
@Autowired
private DeviceDao hibernateDevicDao;
因为有两个 bean 实现了相同的接口。
是否可以配置 bean 以便
1. 我不需要修改现有的类,它们已经具有 HibernateDeviceDao
自动连接
2. 仍然可以像这样使用第二个(新的) bean:
@Autowired
@Qualifier("jdbcDeviceDao")
也就是说,我需要一种方法来将 HibernateDeviceDao
bean 配置为自动连接的默认 bean,同时允许在使用 @Qualifier
注释显式指定时使用 JdbcDeviceDao
。
我试过设置属性
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 没有标记为 autowire 候选项
我将其解释为仍然可以使用 @Qualifier
注释自动连接 JdbcDeviceDao
,并将 HibernateDeviceDao
作为默认 bean。不过,显然我的解释不正确,因为这会导致在启动服务器时出现以下错误消息:
类型[ com.sevenp.mobile.samplemgmt.service.dao.jdbc. JdbcDeviceDao ]的不满意依赖项: 预计至少有1个匹配的 bean
来自我曾经尝试使用限定符自动装配 bean 的类:
@Autowired
@Qualifier("jdbcDeviceDao")
Skaffman 的 建议尝试@Resource 注释是可行的。因此,对于 jdbcDeviceDao,配置的 autowire 候选设置为 false,当使用 jdbcDeviceDao 时,我使用@Resource 注释(而不是@Qualifier)引用它:
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;