Resolving Ambiguous Bean Injection in Spring
Fast recall
Quick revision
Core answer
Whether you know how Spring resolves a common ambiguity and when to reach for @Primary versus @Qualifier.
Assuming Spring silently picks one bean at random, instead of failing fast with NoUniqueBeanDefinitionException.
Give a concrete scenario — email and SMS notifiers — and explain @Primary for the default plus @Qualifier for the exception.
Interview-ready guide
Interview answer
If liveGateway and testGateway both implement PaymentGateway, @Primary on liveGateway makes it the unqualified default. @Qualifier("test") on a parameter can request qualifier metadata attached to testGateway. A parameter named testGateway can sometimes break a final tie by bean name, but relying on parameter names is less explicit. If no rule leaves one candidate, context creation fails with a non-unique-bean cause.
For example, when StripeGateway and PaypalGateway both implement PaymentGateway, @Qualifier("stripeGateway") selects one injection target, while @Primary can define the normal default for unqualified injection.
Resolving Ambiguous Bean Injection in Spring
Direct Answer
When several type-compatible beans exist, Spring applies qualifier metadata, @Primary or priority rules, and finally may use the injection-point name as a fallback. It throws NoUniqueBeanDefinitionException only when required candidate resolution remains ambiguous. A @Qualifier is a selection label and can match more than a literal bean-name interpretation.
Common Mistakes & Pitfalls
- Assuming Spring picks one at random: it doesn't. It fails fast with NoUniqueBeanDefinitionException so a wrong choice never sneaks in silently.
- Marking two beans @Primary: only one bean per type can be primary, so two primaries just produce another exception.
- Loose string qualifiers:
@Qualifier("emailService")with a bare string is fragile — rename the bean and it compiles but fails at runtime. Use a constant or a custom qualifier annotation. - Forgetting name-based matching: if a constructor parameter name matches a bean name, Spring uses that as an implicit qualifier, which can surprise you.
Check your understanding
Answer these without looking back at the article.
- What is NoUniqueBeanDefinitionException?
- How do you inject all implementations of an interface?
- What is the difference between @Primary and @Qualifier?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.