In this example, we will see how to use @Qualifier annotation to resolve ambiguous dependencies.
- This annotation helps fine-tune annotation-based autowiring. There may be scenarios when we create more than one bean of the same type and want to wire only one of them with a property. This can be controlled using @Qualifier annotation along with the @Autowired annotation.
- The @Qualifier is used to resolve ambiguous dependencies i.e, it helps @Autowired annotations to choose one of the dependency.
If there are multiple implementations for single interface then we can use
@Qualifier
to choose required implementation at runtime.
Let's understand the
@Qualifier
with detail example.
Let's take a Message Processing Example - a message can be sent in many ways like email, SMS, twitter etc.
Create
MessageService
interface for multiple message service implementations - EmailService
, SMSService
and TwitterService
classes.public interface MessageService {
public void sendMsg(String message);
}
Create implementations -
EmailService
, SMSService
and TwitterService
classes.public class EmailService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
public class TwitterService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
public class SMSService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
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 injected by both setter and constructor so you can use either one of them.
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());
}
}
Let's test the example using Spring IOC container that is an ApplicationContext object.
public class TestApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
MessageProcessor userService = applicationContext.getBean(MessageProcessor.class);
userService.processMsg("twitter message sending ");
}
}
Output:
twitter message sending
Conclusion
In this example, we have seen how to use @Qualifier annotation to resolve ambiguous dependencies. The implementation of this simple Spring @Qualifier Annotation Example can be found in the GitHub project – this is an Eclipse based project, so it should be easy to import and run as it is.
Github Repository: Spring @Qualifier Annotation Example
Spring Framework Related Posts
- Guide to Dependency Injection in Spring
- Spring Dependency Injection via Setter Example
- Spring Dependency Injection via Constructor Example
- Guide to Spring Bean Scopes
- Singleton and Prototype Bean Scopes Examples
- Spring @Qualifier Annotation Example
- Spring Java Based Configuration Basics
- Spring Java Based Configuration Example
Comments
Post a comment