I know the question of how to create and use two Spring beans of the same type has been answered before, and I've read a little bit about @Qualifier, and @Resource, but all the answers I've seen are in the context of autowiring. In my case the place I'm trying to use the bean is in another part of the config file(s), so I'm not sure which parts of the solution apply. I've also got a case were we're doing config in multiple ways (xml config files, and a java file with the @Configuration annotation. Here's what the code looks like
我知道如何创建和使用两个相同类型的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);
}
...
another spring config xml file imported into application-config.xml
另一个导入到application-config.xml中的spring配置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>
When I do this there's an error trying to create MyConnectionManager in the Java configuration file. The error is on the the constructor arg with the following info ) org.springframework.beans.factory.UnsatisfiedDependencyException .. (excpected single bean but found 2: MyAuthProvider, buildMyConnectionManager())
当我这样做时,在Java配置文件中尝试创建MyConnectionManager时会出现错误。错误位于具有以下信息的构造函数arg上)org.springframe .beans.factory。UnsatisfiedDependencyException . .(异常的单个bean,但发现2:MyAuthProvider, buildMyConnectionManager()))
I also see another bean in here that refers to the AuthProvider class, but instead of just specifying it as an argument into the bean constructor it uses a parameterless constructor and creates a new AuthProvider using the 'buildAuthProvider()' method. I dont' see any complaint about that or the bean created in the xml file, but I'm not sure if this error is just masking the others.
我还在这里看到了另一个引用AuthProvider类的bean,但是它并没有将其指定为bean构造函数的参数,而是使用一个无参数的构造函数,并使用“buildAuthProvider()”方法创建一个新的AuthProvider。我没有看到任何关于这个或xml文件中创建的bean的抱怨,但我不确定这个错误是否只是掩盖了其他错误。
Can someone help me figure out how to have these two separate beans? They get created with a different value passed to their constructor, so I can't re-use the same bean in this case.
有谁能帮我弄明白这两个独立的豆子是怎么来的?它们是用传递给构造函数的不同值创建的,所以在这种情况下,我不能重用相同的bean。
2 个解决方案
#1
4
When working with multiple beans of the same type you need to qualify them with names. In XML configurations, this comes quite naturally with the name="" attribute. In Java based configurations you need to add the name to the annotation, @Bean(name = "").
当使用同一类型的多个bean时,需要用名称对它们进行限定。在XML配置中,name=""属性很自然。在基于Java的配置中,需要将名称添加到注释@Bean(name = "")中。
Next, you can reference the bean from anywhere within the Spring Context. In Java you would use the @Qualifier annotation, which works when declaring Java beans or when using the @Autowired annotation for injection into Spring managed classes.
接下来,您可以从Spring上下文中的任何地方引用bean。在Java中,您将使用@Qualifier注释,它在声明Java bean或在将@Autowired注释注入到Spring托管类时起作用。
Java configuration example:
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
}
}
Do note the location of the @Qualifier annotation, if not in front of the method argument it will not work.
请注意@Qualifier注释的位置,如果不在方法参数前面,它就不能工作。
XML Configuration example:
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>
#2
2
You could use qualifier to distinguish the two beans.
您可以使用限定符来区分这两个bean。
@Bean
@Qualifier("myJDBCTemplate")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Autowired
@Qualifier("myJDBCTemplate")
private JdbcTemplate jdbcTemplate;
#1
4
When working with multiple beans of the same type you need to qualify them with names. In XML configurations, this comes quite naturally with the name="" attribute. In Java based configurations you need to add the name to the annotation, @Bean(name = "").
当使用同一类型的多个bean时,需要用名称对它们进行限定。在XML配置中,name=""属性很自然。在基于Java的配置中,需要将名称添加到注释@Bean(name = "")中。
Next, you can reference the bean from anywhere within the Spring Context. In Java you would use the @Qualifier annotation, which works when declaring Java beans or when using the @Autowired annotation for injection into Spring managed classes.
接下来,您可以从Spring上下文中的任何地方引用bean。在Java中,您将使用@Qualifier注释,它在声明Java bean或在将@Autowired注释注入到Spring托管类时起作用。
Java configuration example:
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
}
}
Do note the location of the @Qualifier annotation, if not in front of the method argument it will not work.
请注意@Qualifier注释的位置,如果不在方法参数前面,它就不能工作。
XML Configuration example:
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>
#2
2
You could use qualifier to distinguish the two beans.
您可以使用限定符来区分这两个bean。
@Bean
@Qualifier("myJDBCTemplate")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Autowired
@Qualifier("myJDBCTemplate")
private JdbcTemplate jdbcTemplate;