![Dynamic Qualifier in Spring Boot](https://tedblob.com/wp-content/uploads/2021/09/image-3.png)
1. Overview
In this article, we will learn about the dynamic qualifier in Spring Boot.
Autowiring by type may lead to multiple candidates, so it is often necessary to have more control over the selection process.
One way to achieve this is with Spring’s @Primary
annotation. @Primary
informs Spring framework to give preference to a particular bean when multiple beans are candidates of autowiring.
@Primary
is an effective way to use autowiring by type with several instances when you can determine one primary candidate. Alternatively, you can use Spring’s @Qualifier
annotation to control the selection process using the bean name.
You could have encountered scenarios where you had to decide the bean to use at runtime.
2. Dynamic Qualifier in Spring Boot
Let’s see a real world example where dynamic qualifier would be significant.
Consider the following interface Vehicle.
public interface Vehicle { String getNumber(); }
Both the Car and Bike classes implement Vehicle interface. We have specified the name for each bean using the @Qualifier
annotation.
@Service @Qualifier("car_vehicle") public class Car implements Vehicle { @Override public String getType() { return "car_vehicle"; } } @Service @Qualifier("bike_vehicle") public class Bike implements Vehicle { @Override public String getType() { return "bike_vehicle"; } }
The following VehicleController
handles the HTTP GET requests /getVehicle
from the client.
Based on the path variable type, we had to either use the bean Car or Bike. Here, we are using the application context to get the bean using its name.
@RestController("/") public class VehicleController { @Autowired private ApplicationContext applicationContext; @GetMapping("/getVehicle/{type}") public String getVehicle(@PathVariable("type") String type) { Vehicle vehicle = applicationContext.getBean(type, Vehicle.class); return vehicle.getType(); } }
If you hit the URL http://localhost:8080/getVehicle/bike_vehicle
, the getVehicle
method returns the value bike_vehicle correctly.
2.1. Use BeanFactory.
The BeanFactory
is the root interface for accessing the Spring bean container and contains utility methods to get specific beans. It is a central registry of application components and centralizes configuration of them.
Since BeanFactory
is a Spring bean, you can autowire and access directly in your class:
@Autowired private BeanFactory beanFactory;
You can use the getBean
method of the BeanFactory
to get the required bean rather than using the application context.
@RestController("/") public class VehicleController { @Autowired private BeanFactory beanFactory; @GetMapping("/getVehicle/{type}") public String getVehicle(@PathVariable("type") String type) { Vehicle vehicle = beanFactory.getBean(type, Vehicle.class); return vehicle.getType(); } }
If you re-run and hit the URL http://localhost:8080/getVehicle/bike_vehicle
, the getVehicle
method returns the value bike_vehicle correctly.
2.2. Autowire all beans into a map
Since Spring 4.3, you can collect all the bean implementations of a particular type into a Map comprising Bean name
as key and Bean instance
as value. You can later determine which one to use at runtime.
For example, the Spring collects all the beans (Car and Bike) of the Vehicle interface in the vehicleMap
.
@Autowired private Map<String, Vehicle> vehicleMap;
At runtime, we will use the bean name passed as the path variable to get the required bean from the Map.
@RestController("/") public class VehicleController { @Autowired private Map<String, Vehicle> vehicleList; @GetMapping("/getVehicle/{type}") public String getVehicle(@PathVariable("type") String type) { Vehicle vehicle = vehicleList.get(type); return vehicle.getNumber(); } }
3. Conclusion
To sum up, we have learned the dynamic qualifier in Spring boot.