当前位置: 首页 > 知识库问答 >
问题:

实现相同接口的两个bean自动连接-如何将默认bean设置为自动连接?

赖浩荡
2023-03-14

我有一个spring 2.5/Java/Tomcat应用程序。下面有一个bean,在整个应用程序的许多地方都使用了这个bean

public class HibernateDeviceDao implements DeviceDao

和以下新bean:

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.NoSuchBeanDefinitionException:未定义类型为[com.sevenp.mobile.samplemGMT.service.dao.deviceDao]的唯一bean:应为单个匹配bean,但找到2:[deviceDao,jdbcDeviceDao]

来自一个试图像这样自动连接bean的类

@Autowired
private DeviceDao hibernateDevicDao;

因为有两个bean实现同一个接口

是否可以将bean配置为

1.我不需要对现有的类进行更改,它们已经具有HibernateDeviceDao自动连线功能

2.仍然能够像这样使用第二个(新的)bean:

@Autowired
@Qualifier("jdbcDeviceDao")

即。我需要一种方法将HibernateDeviceDaobean配置为要自动连线的默认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。请注意,这不会影响按名称显式引用,即使指定的bean未标记为autowire候选项,也会解析该引用。*

我将其解释为我仍然可以使用@qualifier注释自动连接jdbcdevicedao并将hibernatedevicedao作为默认bean。但显然我的解释是不正确的,因为这会导致启动服务器时出现以下错误消息:

类型[class com.sevenp.mobile.samplemGMT.service.dao.jdbc.jdbcdeviceDao]的依赖项不满足:需要至少1个匹配bean

来自我尝试用限定符自动生成bean的类:

@Autowired
@Qualifier("jdbcDeviceDao")

Skaffman尝试@resource注释的建议起作用了。因此,对于jdbcDeviceDao,配置将autowire-candidate设置为false,并且在使用jdbcDeviceDao时,我使用@resource注释(而不是@qualifier)引用它:

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

共有2个答案

路金鑫
2023-03-14

@primary怎么样?

指示当多个候选项有资格自动关联一个单值依赖项时,应优先考虑一个bean。如果候选项中正好存在一个“主”bean,它将是autowired值。这个注释在语义上等同于spring XML中的 元素的primary属性。

@Primary
public class HibernateDeviceDao implements DeviceDao

或者如果您希望默认使用您的Jdbc版本:

<bean id="jdbcDeviceDao" primary="true" class="com.initech.service.dao.jdbc.JdbcDeviceDao">

@primary对于集成测试也很好,您可以通过注释将生产bean轻松替换为Stubed版本。

唐骏祥
2023-03-14

我建议用@primary标记Hibernate DAO类,即(假设您在HibernateDeviceDao上使用了@repository):

@Primary
@Repository
public class HibernateDeviceDao implements DeviceDao

这样它将被选择为默认的autowire candidate,而不需要在另一个bean上使用autowire-candidate

另外,与使用@autowired@qualifier相比,我发现使用@resource来挑选特定的bean,即。

@Resource(name="jdbcDeviceDao")
DeviceDao deviceDao;
 类似资料:
  • 问题内容: 背景: 我有一个Spring 2.5 / Java / Tomcat应用程序。下面的bean在整个应用程序中的许多地方都使用过 以下是新的bean: 第一个bean的配置如下(包含了软件包中的所有bean) 第二个(新)bean是单独配置的 启动服务器时,这(当然)会导致异常: 从试图像这样自动装配bean的类中 因为有两个bean实现相同的接口。 问题: 是否可以配置Bean,以便

  • 有没有可能让一个Spring Bean实现两个接口,并能够使用任何一个接口自动连接Bean? 一个实现两个服务的类 我正在获取: 原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到依赖项[ServiceB]的[ServiceB]类型的合格bean:需要至少有一个bean可以作为此依赖项的自动候选项。依赖项批注

  • 我是Spring的新手。我正面临Spring-Boot的问题。我正在尝试将外部配置文件中的字段自动装配到自动装配的bean中。我有以下类 应用程序。Java语言 AppConfig。Java语言 服务接口 服务1 我无法在App类的postconstruct方法中显示服务名称变量。我这样做对吗?

  • 我有两个类CustomerDAOImpl和UserDAOImpl,都用@Repository注释进行了注释。我在每个类中定义了@bean并自动连接。 与此完全相同,我在UserDAOImpl类方法中定义、自动连接和使用了以下bean(这里只显示bean定义和自动连接代码,以保持简洁): 现在这两个DAO bean都在我的服务类OrderServiceImpl(用@service注释)中自动连接;下

  • 我在如下配置类中创建了一个bean: 在FoodConfig.java 在食品服务课程中,我需要访问食品配置。所以我自动连接了食品配置。 试图从我的FoodServiceTest类访问AbstractFoodService类中的someParam时,我得到一个Nullpointer异常。 然而,若我在AbstractFoodServiceClass的构造函数中注入FoodConfig,它就会工作。

  • 我正在使用Swing和Spring创建一个金融应用程序。在应用程序的一部分中,我有一个,其中包含应用程序中每个的。单击时,我希望在中显示类型的。这都是在下面的控制器中执行的。 会为每个点击更改,因此我将设置为一个原型bean,因此我将为每个帐户接收一个新实例。为了使原型作用域工作,我需要使用。以下是代码: 您将注意到我试图自动连接类型的bean。但是,该bean没有正确地自动连接,它是空的。以下是