我知道如何创建和使用两个相同类型的Spring bean的问题之前已经得到了解答,我已经阅读了一些关于@Qualifier和@Resource的内容,但我看到的所有答案都是在自动装配的背景下。在我的情况下,我正在尝试使用bean的地方是配置文件的另一部分,所以我不确定解决方案的哪些部分适用。我还有一个案例,我们正在以多种方式进行配置(xml配置文件和带有@Configuration注释的java文件。这是代码的样子
import com.this.that.AuthProvider;
@Configuration
...
@Bean
public AuthProvider buildAuthProvider() {
return new AuthProvider(someotherbean);
}
@Bean
public MyConnectionManager buildMyConnectionManager(AuthProvider authProvider) {
return new MyConnectionManager(authProvider);
}
...
另一个spring config xml文件导入到application-config.xml
<bean id="MyAuthProvider" class="com.this.that.AuthProvider">
<constructor-arg type="java.lang.String" ref="somedifferentbean" />
</bean>
<bean id="MyClient" class="com.that.this.MyClient">
<constructor-arg type="com.this.that.AuthProvider"
ref="MyAuthProvider" />
</bean>
当我这样做时,尝试在Java配置文件中创建MyConnectionManager时出错。错误发生在构造函数arg上,其中包含以下信息) org.springframework.beans.factory.UnsatisfiedDependencyException ..(已检测到的单个bean但找到了2:MyAuthProvider,buildMyConnectionManager())
我还在这里看到另一个引用AuthProvider类的bean,但它不是仅仅将它指定为bean构造函数的参数,而是使用无参数构造函数并使用'buildAuthProvider()'方法创建一个新的AuthProvider。我没有看到任何有关该文件或在xml文件中创建的bean的抱怨,但我不确定这个错误是否只是掩盖了其他错误。
有人可以帮我弄清楚如何拥有这两个独立的豆子吗?它们是通过传递给构造函数的不同值创建的,所以在这种情况下我不能重复使用相同的bean。
答案 0 :(得分:4)
使用相同类型的多个bean时,需要使用名称限定它们。在XML配置中,使用 name =&#34;&#34; 属性非常自然。在基于Java的配置中,您需要将名称添加到注释 @Bean(name =&#34;&#34;)。
接下来,您可以在Spring Context中的任何位置引用bean。在Java中,您将使用 @Qualifier 注释,该注释在声明Java bean或使用 @Autowired 注释注入Spring托管类时起作用。
Java配置示例:
@Configuration
public class ApplicationConfiguration {
/**
* Define bean-one, which can be referenced in Java config or XML config.
* @return
*/
@Bean(name = "bean-one")
public String whoAmI(){
return "bean 1.";
}
/**
* Create a bean with the who am I from the XMl config.
* @param whoAmI
* @return
*/
@Bean(name = "xml-message")
public String xmlMessage(@Qualifier("bean-two") String whoAmI){
return "I am " + whoAmI; // I am bean 2
}
/**
* Define the bean with the who am I from the Java config
* @param whoAmI
* @return
*/
@Bean(name="java-message")
public String javaMessage(@Qualifier("bean-one") String whoAmI){
return "I am " + whoAmI; // I am bean 1
}
}
请注意 @Qualifier 注释的位置,如果不在方法参数前面,它将无效。
XML配置示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- Find my other context -->
<context:annotation-config />
<context:component-scan base-package="test.spring"/>
<!-- Declare bean to to be injected into the any of the message objects. -->
<bean class="java.lang.String" name="bean-two">
<constructor-arg value="bean two"/>
</bean>
<!-- Notice that we reference Java config "Bean-One" by using the name assigned -->
<bean class="java.lang.String" name="xml-message-two">
<constructor-arg ref="bean-one"/>
</bean>
<!-- Notice that we reference Java config "Bean-Two" by using the name assigned -->
<bean class="java.lang.String" name="java-message-two">
<constructor-arg ref="bean-two"/>
</bean>
</beans>
答案 1 :(得分:2)
您可以使用限定符来区分两个bean。
@Bean
@Qualifier("myJDBCTemplate")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Autowired
@Qualifier("myJDBCTemplate")
private JdbcTemplate jdbcTemplate;