自动装配两个实现相同接口的bean - 如何将默认bean设置为autowire? [英] Autowiring two beans implementing same interface - how to set default bean to autowire?

查看:179
本文介绍了自动装配两个实现相同接口的bean - 如何将默认bean设置为autowire?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring 2.5 / Java / Tomcat应用程序。有以下bean,在很多地方的应用程序中使用

I have a Spring 2.5/Java/Tomcat application. There is the following bean, which is used throughout the application in many places

public class HibernateDeviceDao implements DeviceDao

以及下面的新豆:

public class JdbcDeviceDao implements DeviceDao

第一个bean配置如此(所有bean都在包括在内)

The first bean is configured so (all beans in the package are included)

<context:component-scan base-package="com.initech.service.dao.hibernate" />

第二个(新)bean单独配置

The second (new) bean is configured separately

<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
    <property name="dataSource" ref="jdbcDataSource">
</bean>

当启动服务器时,这会导致(当然)异常:

This results (of course) in an exception when starting the server:


嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义[com.sevenp.mobile.samplemgmt.service.dao.DeviceDao]类型的唯一bean :期望的单个匹配bean,但找到2:[deviceDao,jdbcDeviceDao]

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao] is defined: expected single matching bean but found 2: [deviceDao, jdbcDeviceDao]

来自尝试像这样自动装配bean的类

from a class trying to autowire the bean like this

@Autowired
private DeviceDao hibernateDevicDao;

因为有两个bean实现了相同的接口。

because there are two beans implementing the same interface.

是否可以配置bean以便

1。我不必对已有 HibernateDeviceDao autowired

1. I don't have to make changes to existing classes, which already have the HibernateDeviceDao autowired

2. 仍然可以像这样使用第二个(新)bean:

2. still being able to use the second (new) bean like this:

@Autowired
@Qualifier("jdbcDeviceDao")

即我需要一种方法来配置 HibernateDeviceDao bean作为要自动装配的默认bean,同时允许使用 JdbcDeviceDao 使用 @Qualifier 注释显式指定时。

I.e. i would need a way to configure the HibernateDeviceDao bean as the default bean to be autowired, simultaneously allowing the usage of a the JdbcDeviceDao when explicitly specifying so with the @Qualifier annotation.

我尝试设置属性

autowire-candidate="false"

在JdbcDeviceDao的bean配置中:

in the bean configuration for JdbcDeviceDao:

<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
    <property name="dataSource" ref="jdbcDataSource"/>
</bean>

因为Spring文档说

because the Spring documentation says that


指示当
寻找匹配的候选者以满足另一个bean的
自动装配要求时是否应该考虑这个bean。 请注意,这不会影响名称显式的
引用,即使指定的
bean未标记为autowire候选,也会解析它。*

我解释为我仍然可以使用 @自动装载 JdbcDeviceDao 限定符注释并将 HibernateDeviceDao 作为默认bean。显然我的解释是不正确的,因为这会在启动服务器时导致以下错误消息:

which I interpreted to mean that I could still autowire JdbcDeviceDao using the @Qualifier annotation and have the HibernateDeviceDao as default bean. Apparently my interpretation was not correct, though, as this results in the following error message when starting the server:


类型[class]的不满意依赖性com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]:预计至少有1个匹配的bean

Unsatisfied dependency of type [class com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: expected at least 1 matching bean

来自班级我尝试使用限定符自动装配bean:

coming from the class where I've tried autowiring the bean with a qualifier:

@Autowired
@Qualifier("jdbcDeviceDao")



解决方案:



skaffman 建议尝试@Resource注释工作。因此,对于jdbcDeviceDao,配置的autowire-candidate设置为false,当使用jdbcDeviceDao时,我使用@Resource注释(而不是@Qualifier)引用它:

Solution:

skaffman's suggestion to try the @Resource annotation worked. So the configuration has autowire-candidate set to false for jdbcDeviceDao and when using the jdbcDeviceDao I refer to it using the @Resource annotation (instead of @Qualifier):

@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;


推荐答案

我建议用<标记Hibernate DAO类a href =http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Primary.html =noreferrer> @Primary ,即(假设您在 HibernateDeviceDao 上使用 @Repository ) :

I'd suggest marking the Hibernate DAO class with @Primary, i.e. (assuming you used @Repository on HibernateDeviceDao):

@Primary
@Repository
public class HibernateDeviceDao implements DeviceDao

这样它将被选为默认的autowire候选者,不需要 autowire-candidate 另一个bean。

This way it will be selected as the default autowire candididate, with no need to autowire-candidate on the other bean.

此外,我发现它更多,而不是使用 @Autowired @Qualifier 优雅使用 @Resource 来挑选特定的豆类,即

Also, rather than using @Autowired @Qualifier, I find it more elegant to use @Resource for picking specific beans, i.e.

@Resource(name="jdbcDeviceDao")
DeviceDao deviceDao;

这篇关于自动装配两个实现相同接口的bean - 如何将默认bean设置为autowire?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆