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.
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 {
8
9 public double getBasePrice() {
10 return 120000;
11 }
12 }
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 {
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.
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;
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")
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);
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.
Related options for your search