In Spring Framework, dependency injection plays a vital role in managing the application's components. However, in situations where multiple beans of the same type exist, it can create ambiguity during autowiring. Spring provides two annotations, @Qualifier and @Primary, to tackle such scenarios and ensure precise bean injection.
In this blog post, we will explore the differences between these annotations and demonstrate their use with practical examples.Next, let's create implementations - EmailService, SMSService, and TwitterService classes.Check out complete code example: Spring @Qualifier Annotation Example
In this blog post, we will explore the differences between these annotations and demonstrate their use with practical examples.
@Qualifier Annotation
The @Qualifier annotation is used to resolve ambiguity when multiple beans of the same type are present in a Spring application context. It allows you to specify a specific bean to be injected by using a qualifier value.
The @Qualifier annotation is used in conjunction with @Autowired to avoid confusion when we have two or more beans configured for the same type. If there are multiple implementations for a single interface then we can use @Qualifier to choose the required implementation at runtime.
For example, consider we have a MessageService interface with multiple implementations - EmailService, SMSService, and TwitterService classes.
MessageService interface
public interface MessageService {
public void sendMsg(String message);
}
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; }
@Primary Annotation
The @Primary annotation is used to indicate a default bean when multiple beans of the same type are present. If multiple beans are eligible for autowiring and none of them are explicitly specified using @Qualifier, the bean marked with @Primary will be selected by default.
Suppose we have two beans implementing the MailSender interface - EmailSender and SmsSender. To set EmailSender as the default bean for autowiring, we can use the @Primary annotation.
@Component
@Primary
public class EmailSender implements MailSender {
// ...
}
@Component
public class SmsSender implements MailSender {
// ...
}
@Service
public class NotificationService {
@Autowired
private MailSender mailSender;
// ...
}
Complete code example: Spring @Primary Annotation Example
Conclusion
To summarize, the @Qualifier annotation is used to resolve ambiguity when multiple beans of the same type exist, whereas the @Primary annotation designates a default bean to be injected when no qualifier is specified. They serve different purposes and can be used together or individually, depending on the desired behavior of bean injection.
Comments
Post a Comment
Leave Comment