In this tutorial, we will see how to use Spring or Spring Boot @Qualifier annotation to resolve ambiguous dependencies.
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.
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.
        
public interface MessageService {
    public void sendMsg(String message);
}
Next, let's 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 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;
    }
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 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 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.