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.

State.java
package org.websparrow.beans.field;

public class State {

	// Generate setters and getters...
	private String stateName;

}
Country.java
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.

spring-field.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">

	<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

Test1.java
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();
	}
}
Output:

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


About the Author

Atul Rai
I like sharing my experiments and ideas with everyone by writing articles on the latest technological trends.