Using @Qualifier to Resolve Ambiguous Beans in Spring Boot
📖 Scenario: You are building a simple Spring Boot application that sends notifications. You have two different notification services: one for email and one for SMS. Both implement the same interface, so Spring does not know which one to use automatically.
🎯 Goal: Learn how to use the @Qualifier annotation to tell Spring Boot exactly which bean to use when there are multiple candidates.
📋 What You'll Learn
Create two service classes implementing the same interface
Create a configuration or component class to inject the correct service using @Qualifier
Use @Qualifier annotation to specify which bean to inject
Run the application to verify the correct service is used
💡 Why This Matters
🌍 Real World
In real applications, you often have multiple implementations of the same interface, like different payment gateways or notification channels. Using @Qualifier helps you pick the right one.
💼 Career
Understanding @Qualifier is essential for Spring developers to manage dependency injection clearly and avoid errors when multiple beans exist.
Progress0 / 4 steps
1
Create NotificationService interface and two implementations
Create an interface called NotificationService with a method sendNotification(String message). Then create two classes: EmailNotificationService and SmsNotificationService that implement NotificationService. Each class should have the @Service annotation and implement the sendNotification method with a simple print statement indicating which service is sending the message.
Spring Boot
Hint
Remember to add @Service annotation on both implementation classes so Spring can detect them as beans.
2
Create a NotificationController with a NotificationService field
Create a class called NotificationController annotated with @RestController. Add a private field of type NotificationService called notificationService. Add a constructor that takes a NotificationService parameter and assigns it to the field.
Spring Boot
Hint
Use constructor injection to assign the notificationService field.
3
Use @Qualifier to specify which NotificationService to inject
Modify the constructor of NotificationController to use @Qualifier("emailNotificationService") on the NotificationService parameter. This tells Spring to inject the EmailNotificationService bean specifically.
Spring Boot
Hint
Use the exact bean name emailNotificationService in the @Qualifier annotation.
4
Add a REST endpoint to send a notification
In NotificationController, add a method sendEmailNotification annotated with @GetMapping("/send"). This method should call notificationService.sendNotification("Hello from Spring Boot!") and return a simple string like "Notification sent".
Spring Boot
Hint
Use @GetMapping("/send") to create a simple GET endpoint.
Practice
(1/5)
1. What is the main purpose of using @Qualifier in Spring Boot?
easy
A. To create a new bean instance automatically
B. To specify which bean to inject when multiple beans of the same type exist
C. To mark a class as a Spring component
D. To configure database connection properties
Solution
Step 1: Understand bean ambiguity in Spring
When multiple beans of the same type exist, Spring cannot decide which one to inject automatically.
Step 2: Role of @Qualifier
@Qualifier explicitly tells Spring which bean to use by specifying its name.
Final Answer:
To specify which bean to inject when multiple beans of the same type exist -> Option B
Quick Check:
@Qualifier = Select specific bean [OK]
Hint: Use @Qualifier to pick one bean among many [OK]
Common Mistakes:
Thinking @Qualifier creates beans
Confusing @Qualifier with @Component
Using @Qualifier for unrelated tasks
2. Which of the following is the correct way to use @Qualifier to inject a bean named "serviceA"?
easy
A. @Autowired @Qualifier(serviceA) private Service service;
B. @Autowired @Qualifier(serviceA) Service service;
C. @Autowired @Qualifier('serviceA') private Service service;
D. @Autowired @Qualifier("serviceA") private Service service;
Solution
Step 1: Check syntax for @Qualifier
@Qualifier requires the bean name as a string literal, so it must be in double quotes.
Step 2: Identify correct option
@Autowired @Qualifier("serviceA") private Service service; uses @Qualifier("serviceA") which is the correct syntax in Java annotations.
Final Answer:
@Autowired @Qualifier("serviceA") private Service service; -> Option D
Quick Check:
String bean name in quotes = correct syntax [OK]
Hint: Always put bean name in double quotes inside @Qualifier [OK]
Common Mistakes:
Omitting quotes around bean name
Using single quotes instead of double quotes
Missing access modifier on field
3. Given the code below, what will be printed when useService() is called?
@Component("serviceA")
class ServiceA implements Service { public String getName() { return "A"; } }
@Component("serviceB")
class ServiceB implements Service { public String getName() { return "B"; } }
@Autowired
@Qualifier("serviceB")
private Service service;
public void useService() {
System.out.println(service.getName());
}
medium
A. B
B. A
C. serviceB
D. Compilation error
Solution
Step 1: Identify injected bean by @Qualifier
@Qualifier("serviceB") tells Spring to inject the bean named "serviceB", which is ServiceB.
Step 2: Check method output
ServiceB's getName() returns "B", so printing service.getName() outputs "B".
Final Answer:
B -> Option A
Quick Check:
@Qualifier("serviceB") injects ServiceB = prints B [OK]
Hint: Qualifier name matches bean name to pick correct implementation [OK]
Common Mistakes:
Assuming default bean is injected without @Qualifier
Confusing bean name with class name
Expecting compilation error due to multiple beans
4. What is the error in the following code snippet?
@Component("serviceA")
class ServiceA implements Service {}
@Autowired
@Qualifier("serviceB")
private Service service;
medium
A. No bean named 'serviceB' found for injection
B. Missing @Component annotation on Service interface
C. Incorrect use of @Autowired without @Qualifier
D. Service interface cannot be injected
Solution
Step 1: Check available beans
Only a bean named "serviceA" is defined; no bean named "serviceB" exists.
Step 2: Effect of @Qualifier("serviceB")
@Qualifier("serviceB") asks Spring to inject a bean named "serviceB", which is missing, causing an error.
Final Answer:
No bean named 'serviceB' found for injection -> Option A
Quick Check:
@Qualifier name must match existing bean [OK]
Hint: Bean name in @Qualifier must exist in context [OK]
Common Mistakes:
Assuming interface needs @Component
Ignoring missing bean name mismatch
Thinking @Autowired alone resolves ambiguity
5. You have two beans of type PaymentService: @Component("paypalService") and @Component("stripeService"). You want to inject stripeService but only want to use constructor injection. Which is the correct way to do this?
hard
A. public class OrderProcessor {
private PaymentService paymentService;
public OrderProcessor() {}
@Autowired
public void setPaymentService(@Qualifier("stripeService") PaymentService paymentService) {
this.paymentService = paymentService;
}
}
B. public class OrderProcessor {
@Autowired
@Qualifier("stripeService")
private PaymentService paymentService;
}
C. public class OrderProcessor {
private final PaymentService paymentService;
public OrderProcessor(@Qualifier("stripeService") PaymentService paymentService) {
this.paymentService = paymentService;
}
}
D. public class OrderProcessor {
@Autowired
public OrderProcessor(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
Solution
Step 1: Understand constructor injection with @Qualifier
To inject a specific bean via constructor, place @Qualifier on the constructor parameter.
Step 2: Identify correct code
public class OrderProcessor {
private final PaymentService paymentService;
public OrderProcessor(@Qualifier("stripeService") PaymentService paymentService) {
this.paymentService = paymentService;
}
} correctly uses @Qualifier("stripeService") on the constructor parameter, ensuring the right bean is injected.
Final Answer:
Constructor with @Qualifier on parameter -> Option C
Quick Check:
Constructor param @Qualifier picks bean [OK]
Hint: Put @Qualifier on constructor parameter for constructor injection [OK]
Common Mistakes:
Using field injection when constructor injection is required
Missing @Qualifier on constructor parameter
Confusing setter injection with constructor injection
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.