Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring -- inject 2 beans of same type

Tags:

java

spring

I like constructor-based injection as it allows me to make injected fields final. I also like annotation driven injection as it simplifies my context.xml. I can mark my constructor with @Autowired and everything works fine, as long as I don't have two parameters of the same type. For example, I have a class:

@Component public class SomeClass {     @Autowired(required=true)     public SomeClass(OtherClass bean1, OtherClass bean2) {         …     } } 

and an application context with:

<bean id="bean1" class="OtherClass" /> <bean id="bean2" class="OtherClass" /> 

There should be a way to specify the bean ID on the constructor of the class SomeClass, but I can't find it in the documentation. Is it possible, or am I dreaming of a solution that does not exist yet?

like image 846
Guillaume Avatar asked Jan 28 '10 10:01

Guillaume


People also ask

How do you inject multiple beans of the same type?

The default autowiring is by type, not by name, so when there is more than one bean of the same type, you have to use the @Qualifier annotation.

Can we have multiple beans of a same type in a class?

The limitation of this approach is that we need to manually instantiate beans using the new keyword in a typical Java-based configuration style. Therefore, if the number of beans of the same class increases, we need to register them first and create beans in the configuration class.

Can we create two beans of same class in Spring?

If you define two beans of same class, without different bean id or qualifiers ( identifier) , Spring container will not be able to understand which bean to be loaded , if you try to access the bean by passing the classname and you will get NoUniqueBeanDefinitionException as there are two qualifying TestBean.


1 Answers

@Autowired is by-type (in this case); use @Qualifier to autowire by-name, following the example from spring docs:

public SomeClass(     @Qualifier("bean1") OtherClass bean1,      @Qualifier("bean2") OtherClass bean2) {     ... } 

Note: In contrast to @Autowired which is applicable to fields, constructors and multi-argument methods (allowing for narrowing through qualifier annotations at the parameter level), @Resource is only supported for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.

(below that text is the full example)

like image 176
Bozho Avatar answered Oct 17 '22 13:10

Bozho