Marcin Majewski
Marcin Majewski

Reputation: 1045

Spring ignoring @Qualifier in very simple program

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

Upvotes: 8

Views: 2084

Answers (2)

Costi Ciudatu
Costi Ciudatu

Reputation: 38235

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.

Upvotes: 7

Yannick Wiesner
Yannick Wiesner

Reputation: 219

You have to make your Point center public:

public Point center;

Spring only has access to public properties an methods.

Upvotes: -3

Related Questions