In this article, we will learn what is @Qualifier annotation in spring with the help of examples.
Table of contents
Definition
Qualifier the term means the one WHO QUALIFIES. Qualifier annotation is used to know which java bean is qualified to be used in a program. If the beans are of different types then it is not an issue, the issue arises when the beans are of the same type.
Beans of different types
package com.getinputs.qualifier; import org.springframework.stereotype.Component; @Component public class Manager { public void getResponsibility() { System.out.println("Manages and coordinate with employees"); } }
package com.getinputs.qualifier; import org.springframework.stereotype.Component; @Component public class SEDeveloper { public void getResponsibility() { System.out.println("Developing and testing the codebase"); } }
package com.getinputs.qualifier; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class BusinessClient { @Autowired Manager manager; public void getResponsibility() { manager.getResponsibility(); } } Note : "BusinessClient" knows it needs the "Manager" bean
package com.getinputs.qualifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class QualifierDemo { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.getinputs.qualifier"); context.refresh(); BusinessClient businessClient = context.getBean(BusinessClient.class); businessClient.getResponsibility(); } } O/P : Manages and coordinate with employees
In the above example Manager
and SEDeveloper
beans are of 2 different types. The BusinessClient
class asks for Manager
bean hence the spring container provides Manager
bean. Now consider a case where there is a relationship between the Manager
and SEDeveloper
beans, we will try to understand it better below.
Beans of the same type
package com.getinputs.qualifier; public interface Employee { public void getResponsibility(); }
package com.getinputs.qualifier; import org.springframework.stereotype.Component; @Component public class Manager implements Employee { public void getResponsibility() { System.out.println("Manages and coordinate with employees"); } }
package com.getinputs.qualifier; import org.springframework.stereotype.Component; @Component public class SEDeveloper implements Employee { public void getResponsibility() { System.out.println("Developing and testing the codebase"); } }
Manager
and SEDeveloper
implements the same Employee
interface, now in BusinessClient
we will Autowire the Employee
interface and check the behavior.
package com.getinputs.qualifier; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class BusinessClient { @Autowired Employee employee; public void getResponsibility() { employee.getResponsibility(); } }
package com.getinputs.qualifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class QualifierDemo { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.getinputs.qualifier"); context.refresh(); BusinessClient businessClient = context.getBean(BusinessClient.class); businessClient.getResponsibility(); } }
Output : Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.getinputs.qualifier.Employee’ available: expected single matching bean but found 2: manager,SEDeveloper
The Spring container gets confused because there are 2 beans that are of the same Employee
type and it’s an ambiguity issue. So to remove such kind of ambiguity issue we have to use Qualifier annotation.
Using @Qualifier annotation without alias name
package com.getinputs.qualifier; public interface Employee { public void getResponsibility(); }
package com.getinputs.qualifier; import org.springframework.stereotype.Component; @Component("manager") public class Manager implements Employee { public void getResponsibility() { System.out.println("Manages and coordinate with employees"); } } Note : Given a alias as "manager"
package com.getinputs.qualifier; import org.springframework.stereotype.Component; @Component("seDeveloper") public class SEDeveloper implements Employee { public void getResponsibility() { System.out.println("Developing and testing the codebase"); } } Note : Given a alias as "seDeveloper"
package com.getinputs.qualifier; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class BusinessClient { @Autowired @Qualifier("manager") Employee employee; public void getResponsibility() { employee.getResponsibility(); } } Note : Using the Qualifier annotation we are giving a instruction to Container to use the "Manager" bean.
package com.getinputs.qualifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class QualifierDemo { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.getinputs.qualifier"); context.refresh(); BusinessClient businessClient = context.getBean(BusinessClient.class); businessClient.getResponsibility(); } } O/P : Manages and coordinate with employees
Important Note: Instead of using the name from the Component annotation we can make use of the Qualifier annotation in the Bean classes.
Using @Qualifier annotation with alias name
package com.getinputs.qualifier; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component("manager") @Qualifier("alias-manager") public class Manager implements Employee { public void getResponsibility() { System.out.println("Manages and coordinate with employees"); } }
package com.getinputs.qualifier; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class BusinessClient { @Autowired @Qualifier("alias-manager") Employee employee; public void getResponsibility() { employee.getResponsibility(); } } Note : In BusinessClient class we can make use of "manager" alias or "alias-manager" alias . Both will work as expected .
package com.getinputs.qualifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class QualifierDemo { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.getinputs.qualifier"); context.refresh(); BusinessClient businessClient = context.getBean(BusinessClient.class); businessClient.getResponsibility(); } } O/P : Manages and coordinate with employees
I hope you found this article interesting and valuable. If you are having any concerns or questions about this article please comment below.