I have Circle class:
public class Circle
{
@Autowired
@Qualifier("pointA")
private Point center;
public Point getCenter()
{
return center;
}
public void setCenter(Point center)
{
this.center = center;
}
}
point class:
public class Point
{
private int x;
private int y;
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
}
And my spring 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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
>
<bean id="pointA" name="pointA" class="SpringTest.Point">
<qualifier value="pointA"/>
<property name="x" value="4"/>
<property name="y" value="4"/>
</bean>
<bean id="pointB" name="pointB" class="SpringTest.Point">
<property name="x" value="2"/>
<property name="y" value="5"/>
</bean>
<bean id="circle" class="SpringTest.Circle">
</bean>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
</beans>
As far as I am concerned this should work like this: 1. Spring see @Autowire annotation 2. Spring realizes that there are many beans of Point type 3. Spring uses @Qualifier annotation to determine which bean to inject
Unfortunaltely it is not working like that. While executing:
AbstractApplicationContext abstractApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
BeanFactory beanFactory = abstractApplicationContext.getBeanFactory();
I am getting an error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'circle': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private SpringTest.Point SpringTest.Circle.center; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [SpringTest.Point] is defined: expected single matching bean but found 2: pointA,pointB
I am beginner at spring topic but I believe @Qualifier annotation should do the job and determine which bean to use.
Startup log: https://gist.github.com/mmajews/384207ee97b2cc8bd49a
NOTE: if you are creating bean with @Bean, it will be injected byType if there is duplicates then it will injected byName. we no need to mention @Bean(name="bmwDriver") . so you can directly use qualifier("bmwDriver") wherever you need in classes.
By using the @Qualifier annotation, we can eliminate the issue of which bean needs to be injected. By including the @Qualifier annotation, together with the name of the specific implementation we want to use, in this example Foo, we can avoid ambiguity when Spring finds multiple beans of the same type.
Spring @Primary vs @Qualifier We use @Qualifier in Spring to autowire a specific bean among same type of beans, where as @Primary is used to give high preference to the specific bean among multiple beans of same type to inject to a bean.
There may be a situation when you create more than one bean of the same type and want to wire only one of them with a property. In such cases, you can use the @Qualifier annotation along with @Autowired to remove the confusion by specifying which exact bean will be wired.
You need to add <context:annotation-config/>
in your spring xml, rather than instantiating the AutowiredAnnotationBeanPostProcessor
, as that does not handle @Qualifier
annotations.
Or, if you really want to control everything that gets instantiated in your context, have a look at the actual candidate resolver for @Qualifier
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With