What is the use of @Qualifier annotation in Spring?
Ahmed Abdelaziz
Software Engineer Team Leader at IST Networks | Java Champion ??| Java and Web technologies Expert |Solutions Architect | Spring Boot Expert | Microservices | Databases | Expert in GENESYS,CISCO and Sprinklr CC solutions
he use of @Qualifier is to support the @Autowired annotation when it needs help.
Typically, @Autowired can implicitly, automatically inject a Spring managed bean by type. In some cases (like the example above), you may have multiple beans implementing the same interface like Animal.
When two or more beans implement the same interface, @Qualifier is used to tell @Autowired what exactly to inject.
Spring @Qualifier Annotation Example
Let's take a Message Processing Example - a message can be sent in many ways like Email, SMS, Twitter, etc.
? Let's create a MessageService interface for multiple message service implementations - EmailService, SMSService, and TwitterService classes.
MessageService interface
public interface MessageService {
public void sendMsg(String message);
}
Next, let's create implementations - EmailService, SMSService, and TwitterService classes.
EmailService Class
public class EmailService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
SMSService Class
public class TwitterService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
TwitterService Class
public class SMSService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
MessageProcessor Interface and MessageProcessorImpl Class
It's time to see the usage of @Qualifier annotation.
public interface MessageProcessor {
public void processMsg(String message);
}
public class MessageProcessorImpl implements MessageProcessor {
private MessageService messageService;
// setter based DI
@Autowired
@Qualifier("twitterService")
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}
// constructor based DI
@Autowired
public MessageProcessorImpl(@Qualifier("twitterService") MessageService messageService) {
this.messageService = messageService;
}
public void processMsg(String message) {
messageService.sendMsg(message);
}
}
In the above example, Dependency is injected by both setter and constructor so you can use either one of them.
We have used?@Qualifier to inject TwitterService bean using constructor injection:
// setter based DI
@Autowired
@Qualifier("twitterService")
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}
We have used?@Qualifier to inject the TwitterService bean using setter injection:
// constructor based DI
@Autowired
public MessageProcessorImpl(@Qualifier("twitterService") MessageService messageService) {
this.messageService = messageService;
}
If you want to inject EmailService bean instead of TwitterService bean then you can simply pass bean EmailService bean name. For example:
// constructor based DI
@Autowired
public MessageProcessorImpl(@Qualifier("emailService") MessageService messageService) {
this.messageService = messageService;
}
AppConfiguration
Let's write the java based configuration.
@Configuration
@ComponentScan("com.javadevsguide.springframework.di")
public class AppConfiguration {
@Bean(name="emailService")
public MessageService emailService(){
return new EmailService();
}
@Bean(name="twitterService")
public MessageService twitterService(){
return new TwitterService();
}
@Bean(name="smsService")
public MessageService smsService(){
return new SMSService();
}
@Bean
public MessageProcessor messageProcessor(){
return new MessageProcessorImpl(twitterService());
}
}
Testing
Let's test the example using the Spring IOC container which is an ApplicationContext object.
public class TestApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
MessageProcessor processor = applicationContext.getBean(MessageProcessor.class);
processor.processMsg("twitter message sending ");
}
}
Output:
twitter message sending
Conclusion
In?this example, we have seen how to use?@Qualifier annotation?in conjunction with?@Autowired?to avoid confusion when we have two or more beans configured for the same type.