自动装配两个实现相同接口的bean - 如何设置默认bean进行自动装配?

11 浏览
0 Comments

自动装配两个实现相同接口的bean - 如何设置默认bean进行自动装配?

背景:

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

public class HibernateDeviceDao implements DeviceDao

\n还有一个新的bean:\n

public class JdbcDeviceDao implements DeviceDao

\n第一个bean的配置如下(包中的所有bean都被包括在内):\n


\n第二个(新的)bean被单独配置:\n


    

\n当启动服务器时,会出现以下异常:\n

\nnested 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]\n

\n这是由于有两个实现了相同接口的bean,导致一个类试图通过自动装配来使用这个bean时产生的异常,如下所示:\n

@Autowired
private DeviceDao hibernateDevicDao;

\n

问题:

\n是否有可能配置这些bean,以便:\n1. 我不需要对已经自动装配了HibernateDeviceDao的现有类进行更改\n2. 仍然能够像这样使用第二个(新的)bean:\n

@Autowired
@Qualifier("jdbcDeviceDao")

\n也就是说,我需要一种方法将HibernateDeviceDaobean配置为默认的自动装配bean,同时允许使用@Qualifier注解来显式指定使用JdbcDeviceDao。\n

我已经尝试过的:

\n我尝试在JdbcDeviceDao的bean配置中设置属性\n

autowire-candidate="false"

\n因为Spring文档中说到:\n

\nIndicates whether or not this bean should be considered when \n looking for matching candidates to satisfy another bean\'s \n autowiring requirements. Note that this does not affect explicit \n references by name, which will get resolved even if the specified \n bean is not marked as an autowire candidate.*\n

\n我理解这意味着我仍然可以使用@Qualifier注解自动装配JdbcDeviceDao,并将HibernateDeviceDao作为默认bean。然而,显然我的理解是错误的,因为当启动服务器时,会出现以下错误消息:\n

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

\n这是来自我尝试使用限定符自动装配bean的类产生的错误消息:\n

@Autowired
@Qualifier("jdbcDeviceDao")

\n

解决方案:

\nskaffman建议尝试使用@Resource注解是有效的。因此,配置中将jdbcDeviceDao的autowire-candidate设置为false,并在使用jdbcDeviceDao时使用@Resource注解(而不是@Qualifier):\n

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

0
0 Comments

在Spring 2.5中,没有提供@Primary注解来设置默认自动装配的bean。唯一的方法是使用@Qualifier注解。

在某些情况下,我们可能会有多个实现同一个接口的bean,而我们想要将其中一个bean设置为默认自动装配的bean。然而,在Spring 2.5中,并没有直接的方式来实现这一点。

解决这个问题的方法是使用@Qualifier注解来指定要自动装配的bean的名称。首先,我们需要在多个实现同一个接口的bean上使用@Qualifier注解来为它们命名。然后,在要进行自动装配的地方,使用@Autowired注解并指定要自动装配的bean的名称,如下所示:

public interface MyInterface {
    void doSomething();
}
@Component
@Qualifier("beanA")
public class BeanA implements MyInterface {
    @Override
    public void doSomething() {
        // 实现逻辑
    }
}
@Component
@Qualifier("beanB")
public class BeanB implements MyInterface {
    @Override
    public void doSomething() {
        // 实现逻辑
    }
}
@Component
public class MyComponent {
    @Autowired
    @Qualifier("beanA")
    private MyInterface myInterface;
    
    // ...
}

在上面的示例中,我们定义了一个接口MyInterface,并有两个实现它的bean:BeanABeanB。我们使用@Qualifier注解为它们命名为beanAbeanB。然后,在MyComponent类中,我们使用@Autowired注解并指定要自动装配的bean的名称为beanA,这样myInterface字段就会自动装配为BeanA的实例。

通过使用@Qualifier注解,我们可以明确地指定要自动装配的bean的名称,从而解决了在Spring 2.5中没有@Primary注解的问题。

0
0 Comments

问题出现的原因是:当有多个候选bean符合自动装配的条件时,如何设置默认的bean进行自动装配。

解决方法是使用`@Primary`注解。`@Primary`注解表示在多个候选bean中,给定的bean应该被优先选择进行自动装配。如果在候选bean中恰好存在一个"primary" bean,它将被自动装配为值。这个注解在语义上等同于Spring XML中``元素的`primary`属性。

另外,可以通过在bean上添加`primary="true"`属性来设置默认的bean进行自动装配。例如,在XML配置文件中声明``,表示默认使用Jdbc版本的bean进行自动装配。

如果使用Spring 2.5版本,不能使用`@Primary`注解,可以通过在XML配置文件中声明`HibernateDeviceDao`并将其排除在组件/注解扫描之外来解决问题。

注意:根据文档,`@Primary`注解从Spring 3.0版本开始可用。因此,如果使用Spring 3.x版本,可以使用`@Primary`注解来解决问题。

0
0 Comments

问题的原因是有两个实现了同一个接口的bean,希望能够设置一个默认的bean进行自动装配。解决方法是使用`@Primary`注解标记Hibernate DAO类,将其设置为默认的自动装配候选者,而不需要在另一个bean上使用`autowire-candidate`属性。另外,可以使用`@Resource`注解来选择特定的bean。

在Spring 2.5中,`@Primary`注解不可用,可以尝试使用`@Resource`注解来解决这个问题。使用`@Resource`注解可以将bean标记为依赖注入的目标,并在一行中指定名称。注意,simon的解决方案是多余的,可以移除`@Autowired`注解。

总之,通过使用`@Primary`注解标记默认的自动装配候选者,并使用`@Resource`注解来选择特定的bean,可以解决这个问题。

0