@Qualifier annotation in spring
The @Qualifier annotation is provided by spring framework which inject the specified named bean to the property of another or dependent bean when there are multiple bean found for the same type. If there are more than one bean of the same type is available in the IOC container, the framework will throw NoUniqueBeanDefinitionException, indicating that more than one bean is available for autowiring.
The @Qualifier annotation used to avoid ambiguity when there are more than one bean of the same type is available in the IOC container by specifying the name or Id to @Qualifier annotation to inject the required bean to the dependent class bean.

Example

Base abstract service class
 1 package com.iogyan.service;
 2 
 3 public abstract class CarService {
 4 
 5 	abstract double getBasePrice();
 6 }
 7 
Inn the above example, a CarService is define as abstract with abstract method getBasePrice(), a derived must provides an implementation of the getBasePrice() method.
AudiService class
 1 package com.iogyan.service;
 2 
 3 import org.springframework.stereotype.Service;
 4 import com.iogyan.service.CarService;
 5 
 6 @Service
 7 public class AudiService extends CarService { // extending CarService class
 8 
 9     public double getBasePrice() {
 10         return 120000;
 11     }
 12 }
TataService class
 1 package com.iogyan.service;
 2 
 3 import org.springframework.stereotype.Service;
 4 import com.iogyan.service.CarService;
 5 
 6 @Service
 7 public class TataService extends CarService { // extending CarService class
 8 
 9     public double getBasePrice() {
 10         return 100000;
 11     }
 12 }
In the above example, a AudiService and TataService class are created by extending a CarService and by providing an implementation of getBasePrice() method. A classes are created by annotating with @Service annotation which will creates two spring bean of each classes. A requested bean dependency will be injected on when requested.
Controller class
 1 package com.iogyan.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Controller;
 5 import com.iogyan.service.CarService;
 6 
 7 @Controller
 8 public class CarController {
 9 
 10     @Autowired
 11     private CarService carService; // requesting dependency with parent class
 12 
 13     public double getBasePrice() {
 14         return this.carService.getBasePrice();
 15     }
 16 }
In the above example, a Controller class is created with dependency of CarService which is parent class of AudiCar and TataCar service that annotated with @Autowire which inject dependency based on class type.
ApplicationConfiguration class
 1 package com.iogyan.example;
 2 
 3 import org.springframework.context.annotation.ComponentScan;
 4 
 5 @ComponentScan(basePackages = "com.iogyan")
 6 public class ApplicationConfiguration {
 7 
 8 }
 9 
The above ApplicationConfiguration class, perform scanning of specified package using @ComponentScan annotation. It will create three different spring beans for the application. There are two different service bean and one for controller.
Reading configuration file and execute service method
 1 package com.iogyan.example;
 2 
 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 4 import com.iogyan.controller.CarController;
 5 
 6 public class Example {
 7 
 8     public static void main(String[] args) {
 9 
 10         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
 11 
 12         try {
 13             ctx.register(ApplicationConfiguration.class);
 14             ctx.refresh();
 15 
 16             CarController controller = ctx.getBean(CarController.class);
 17             double price = controller.getBasePrice();
 18 
 19             System.out.println(price);
 20         } catch (Exception e) {
 21             ctx.close();
 22         }
 23     }
 24 }
In the above example, the application throws an exception on startup. The exception will be Unsatisfied dependency expressed through field 'carService'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.iogyan.service.CarService' available: expected single matching bean but found 2: audiService,tataService

Resolve duplicate dependency with @Qualifier annotation

To fix the above exception @Qualifier annotation can be used to avoid ambiguity with @Autowired annotation by specifying the name or Id of the spring bean in the argument of @Qualifier annotation as below in the CarController
Adding @Qualifier annotation in the controller class CarService property
 1 package com.iogyan.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Qualifier;
 5 import org.springframework.stereotype.Controller;
 6 
 7 import com.iogyan.service.CarService;
 8 
 9 @Controller
 10 public class CarController {
 11 
 12     @Autowired
 13     @Qualifier("tataService") // requesting named bean by specifying name or bean ID
 14     private CarService carService;
 15 
 16     public double getBasePrice() {
 17 
 18         return this.carService.getBasePrice();
 19     }
 20 }
In the above example, a CarController property define with @Autowire and @Qualifier annotation by specifying a bean ID value as tataService. It injects a bean of class type TataService class into the CarService property of CarController before it calls getBasePrice() method.
Reading configuration and executing example
 1 package com.iogyan.example;
 2 
 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 4 import com.iogyan.controller.CarController;
 5 
 6 public class Example {
 7 
 8     public static void main(String[] args) {
 9 
 10         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
 11 
 12         try {
 13             ctx.register(ApplicationConfiguration.class);
 14             ctx.refresh();
 15 
 16             CarController controller = ctx.getBean(CarController.class);
 17             double price = controller.getBasePrice();
 18 
 19             System.out.println(price); // print 100000.0
 20         } catch (Exception e) {
 21             ctx.close();
 22         }
 23     }
 24 }
In the above code, an instance of AnnotationConfigApplicationContext is created using constructor method. A context method register() method called by specifying a name of ApplicationConfiguration class and refresh() the bean definitions in spring container. A context method getBean() method called by specifying a CarController class name. It returns bean of CarController, a method getBasePrice() is called where spring bean TataService will be injected in controller that call service method which will returns string message.
Output
 1 10000.0
Privacy Policy
Terms of Service
Disclaimer
Contact us
About us