There is an interface

public interface AddressInt { } 

Class that implements this interface

 public class AddressA implements AddressInt { private String state; private String town; private String street; } 

The second class that implements this interface (it is the same, but it does not matter)

 public class AddressB implements AddressInt { private String state; private String town; private String street; } 

A class that uses an interface type.

 public class Employee { private String name; private String position; @Autowired @Qualifier("addressA") private AddressInt address; } 

Main method

 public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("mySpringXMLConfig.xml"); Employee empl = (Employee)context.getBean("employee"); System.out.println(empl); } 

Configured so

 <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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd "> <!--Register AutowiredAnnotationBeanPostProcessor--> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> <!--<context:annotation-config/>--> <bean id="employee" class="by.Employee"> <property name="name" value="Nick Smith"/> <property name="position" value="Java developer"/> </bean> <bean id="addressA" class="by.AddressA"> <property name="state" value="NY"/> <property name="town" value="New York city"/> <property name="street" value="5"/> </bean> <bean id="addressB" class="by.AddressB"> <property name="state" value="IL"/> <property name="town" value="Chicago"/> <property name="street" value="37"/> </bean> </beans> 

Classics of the genre and everything is simple, but when executed

 org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [by.AddressInt] is defined: expected single matching bean but found 2: [addressA, addressB] 

Googled For other people, I see the reasons for the refusal; The qualifier tried to set in different ways (and in xml, and to write the summary), but the result is one. What is the secret?

  • Zanadka. Try org.springframework.beans.factory.annotation.Qualifier . - talex
  • @talex I am sorry that I did not give it in my source code, but this class is imported into my Employee - Val
  • Should work. Try a full project recompilation. Maybe something is stuck :) - talex
  • @talex Cleaned and reassembled (NetBeans project using Maven), launched. Does not matter. I have java 1.8, and Spring 2.5.6. Maybe the dog is buried here, do you think? - Val
  • And the Service / Component annotation where did you go?) - GenCloud

1 answer 1

AutowiredAnnotationBeanPostProcessor does not support the @Qualifier annotation. To process it, you need to use <context:annotation-config/> instead.

But there is one nuance .

<context:annotation-config/> runs on Java 5 and above. However, Spring 2.5.6 does not know about the existence of Java above version 7, and all that is not 5, 6 or 7 it considers Java 4. Therefore, if you run Java project with <context:annotation-config/> and Spring 2.5, under Java 8. 6, you will get the most amazing error Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser] are only available on JDK 1.5 and higher .

This can be solved in four ways. The first , and most preferred, is to upgrade Spring. The current version is 5.1.3, but Java 8 support appeared in 4.0.3. If for some reason this does not suit you, then the second option is to add the address* property primary="true" to one of the bean declarations. Then AutowiredAnnotationBeanPostProcessor will use it exactly where there is more than one candidate of this type. If you want to use addressA in one place, and addressA in another, and circumstances do not allow you to update Spring, then the third option is at your service - to refuse @Autowired and explicitly inject bins in the config file. Well, the fourth option is to run your program under Java 5-7. I highly recommend not to do this, because the JRE of these versions is not supported, and may contain vulnerabilities and bugs that will never be fixed.

  • Thank you so much for the comprehensive answer! Changed the version of Spring and now everything works :-) - Val