@Qualifier Annotation in Spring

By Arvind Rai, March 20, 2022
This page will walk through Spring @Qualifier annotation example.
1. The @Qualifier may be used on a field or parameter as a qualifier for candidate beans when autowiring.
2. In the scenario where more than one beans are eligible to be autowired, we use @Qualifier annotation.
3. The same scenario can also be handled by @Primary annotation. The @Qualifier defines more robust selection criteria than @Primary annotation.
4. We can also use @Qualifier to create custom qualifier annotation.

@Qualifier at Field level

Here we are using @Qualifier at field level.
@Service
public class AnimalService {
    @Autowired
    @Qualifier("fox")
    private Animal animal;

    public Animal getAnimal() {
	return animal;
    }
    ------
} 
The bean with name fox will be autowired.
Find the other files of our demo.
Animal.java
package com.concretepage;
public interface Animal {
   void printName();
} 
Deer.java
package com.concretepage;
import org.springframework.stereotype.Component;

@Component("deer")
public class Deer implements Animal {
	@Override
	public void printName() {
		System.out.println("I am Deer");
	}
} 
Fox.java
package com.concretepage;
import org.springframework.stereotype.Component;

@Component("fox")
public class Fox implements Animal {
	@Override
	public void printName() {
		System.out.println("I am Fox");
	}
} 
AnimalService.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class AnimalService {
    @Autowired
    @Qualifier("deer")
    private Animal animal;

    public Animal getAnimal() {
	return animal;
    }
} 
When we pass a value in @Component as @Component("fox"), then fox becomes the bean name.
We can see that Fox and Deer both components are the implementations of Animal interface. In AnimalService class, we have autowired the animal property for which two beans are eligible to be injected i.e. fox and deer.
Case-1: When we write the code as below.
@Autowired
private Animal animal; 
An error will be thrown.
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.concretepage.Animal] is defined: expected single matching bean but found 2: deer,fox 
Case-2: To solve the error, use @Qualifier annotation.
@Autowired
@Qualifier("deer")
private Animal animal; 
The Deer component will be injected.
Now run the code.
SpringDemo.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringDemo {
	public static void main(String[] args) {
	    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
	    ctx.register(AppConfig.class);
	    ctx.refresh();
	    AnimalService animal = ctx.getBean(AnimalService.class);
	    animal.getAnimal().printName();
	}
} 
Output
I am Deer 

@Qualifier at Parameter level

Here we are using @Qualifier at parameter level.
@Service
public class AnimalService {
  @Autowired
  public AnimalService(@Qualifier("deer") Animal animal){
	this.animal = animal;
  }
  ------
} 

@Qualifier vs @Primary

For the case when more than one beans are eligible to be autowired, we can also use @Primary annotation. The @Primary annotation is used to make a bean preferable when multiple beans are qualified to autowire a single-valued dependency.
Find the example to use @Primary.
@Component("fox")
@Primary
public class Fox implements Animal {
  ------
} 
Now autowire the Animal property of a class.
@Autowired
private Animal animal; 
The fox bean will be injected because it is primary.
To inject deer bean, specify it by using @Qualifier annotation.
@Autowired
@Qualifier("deer")
private Animal animal; 

Autowire byName

To handle the scenario where more than one beans are eligible to be autowired, we can also use the XML <bean> with byName configuration. The byName is a value of autowire property of XML <bean> element. If there are more than one beans of same class with different bean names in our XML configuration, then with the use of byName, the autowiring will not conflict and take the matching bean name with class property name.
<bean name="employee" class="com.concretepage.Employee" autowire="byName">
        <property name="empName" value="Mahesh"/>
</bean> 
<bean name="permanentAddress" class="com.concretepage.Address">
	<property name="city" value="Varanasi"/>
	<property name="state" value="Uttar Pradesh"/>
</bean>   
<bean name="localAddress" class="com.concretepage.Address">
	<property name="city" value="Bhopal"/>
	<property name="state" value="Madhya Pradesh"/>
</bean> 
Find the class which is using @Autowired annotation.
public class Employee {
   @Autowired
   private Address localAddress;
   ------
} 
In XML configuration, there are two beans of Address class type, localAddress and permanentAddress. The Employee class has an autowired property and this will be injected with matching bean name that is localAddress.

Reference

Spring @Qualifier

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us