Spring 5 @Qualifier annotation example
To resolve the autowiring conflicts we can use the Spring @Qualifier
annotation, when multiple beans of the same type available in the configuration file. In the last tutorial, we have learned Spring @Autowired annotation and it internally uses the byType mechanism so it may throw the exception.
Spring @Qualifier
annotation can be used along with @Autowired
annotation. It can be used for fields, setters method, and constructors. Pass the required bean id name to the @Qualifier("s1")
or @Qualifier(value="s1")
, Spring container will inject only the desired bean value automatically.
See the below configuration file, it has two eligible beans.
<!-- First eligible bean -->
<bean id="s1" class="org.websparrow.beans.field.State">
<property name="stateName" value="Uttar Pradesh" />
</bean>
<!-- Second eligible bean -->
<bean id="s2" class="org.websparrow.beans.field.State">
<property name="stateName" value="Delhi" />
</bean>
<bean id="country" class="org.websparrow.beans.field.Country" />
In this case, Spring container will unable to identify which bean value should I inject and throw the exception.
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'country': Unsatisfied dependency expressed through field 'state'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.websparrow.beans.field.State' available: expected single matching bean but found 2: s1,s2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.websparrow.beans.field.State' available: expected single matching bean but found 2: s1,s2
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:215)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1113)
We can resolve it by using @Qualifier
annotation. Let’s check the complete example.
Spring Beans
Create the bean classes for autowiring using @Autowired
annotation along with @Qualifier
and pass the desired bean id name. Spring will consider only reference bean value for injection. And a method to print the data on console log.
package org.websparrow.beans.field;
public class State {
// Generate setters and getters...
private String stateName;
}
package org.websparrow.beans.field;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Country {
@Autowired
@Qualifier("s1") // eligible reference bean id
private State state;
public void display() {
System.out.println("State name is: " + state.getStateName());
}
}
Spring Beans Configuration
I have just copied the above XML configuration metadata. It has two eligible beans for autowiring.
<?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">
<context:annotation-config />
<!-- First eligible bean -->
<bean id="s1" class="org.websparrow.beans.field.State">
<property name="stateName" value="Uttar Pradesh" />
</bean>
<!-- Second eligible bean -->
<bean id="s2" class="org.websparrow.beans.field.State">
<property name="stateName" value="Delhi" />
</bean>
<bean id="country" class="org.websparrow.beans.field.Country" />
</beans>
Run it
Load the configuration and run it
package org.websparrow.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.websparrow.beans.field.Country;
public class Test1 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-field.xml");
Country c = (Country) context.getBean("country");
c.display();
}
}
You will see, no exception has been thrown. All works fine and print the result on console log.
State name is: Uttar Pradesh
Download Source Code: spring5-qualifier-annotation-example