What to Do If There Are Multiple Beans of the Same Type?
If Spring finds multiple beans of the same type -> error!
Junior Level
If Spring finds multiple beans of the same type -> error!
Solutions:
1. @Primary - primary bean:
@Primary
@Bean
public PaymentService defaultPayment() { ... }
2. @Qualifier - explicit choice:
@Autowired
@Qualifier("stripePayment")
private PaymentService payment;
3. Variable name:
@Autowired
private PaymentService stripePayment; // By bean name!
Middle Level
Resolution Order
1. @Qualifier - explicit filter by name (highest priority)
2. @Primary - global "default" marker
3. Variable name (byName) - if no @Qualifier and @Primary
4. @Priority (JSR-250) - numeric priority at class level
Injecting All Beans
// All PaymentService implementations
@Autowired
List<PaymentService> allPayments;
// Map: bean name -> bean
@Autowired
Map<String, PaymentService> paymentMap;
// Usage:
PaymentService service = paymentMap.get("stripe");
ObjectProvider
@Autowired
ObjectProvider<PaymentService> provider;
PaymentService service = provider.getIfAvailable(
() -> new DefaultPaymentService() // Fallback!
);
Senior Level
Custom Qualifiers
@Qualifier
@Retention(RUNTIME)
public @interface StripePayment { }
@StripePayment
@Bean
public PaymentService stripePayment() { ... }
@Autowired
@StripePayment
private PaymentService payment;
// -> Type-safe, no typos!
NoUniqueBeanDefinitionException Diagnostics
// Spring Boot FailureAnalyzer automatically shows all found beans
// on NoUniqueBeanDefinitionException - no need to dig into stack trace.
Production Experience
Real scenario: 10 implementations
Strategy pattern:
-> Map<String, Strategy> strategies
-> Selection by key at runtime
-> Without if/else!
Best Practices
- @Primary -> one primary bean
- @Qualifier -> explicit choice
- Map -> Strategy pattern
- Custom qualifiers -> type-safe
- ObjectProvider -> fallback
- @ConditionalOnMissingBean -> in starters
Summary for Senior
- @Primary -> default bean
- @Qualifier -> precise choice
- Map -> all beans, selection by key
- Custom qualifiers -> type-safe
- ObjectProvider -> lazy + fallback
- FailureAnalyzer -> error diagnostics
Interview Cheat Sheet
Must know:
- Resolution order: @Qualifier -> @Primary -> byName -> @Priority (JSR-250)
- @Primary - global “default bean” marker for a given type
- @Qualifier - explicit filter by name, highest priority
- Inject all beans: List
(order) or Map<String, T> (name -> bean) - Strategy pattern - ObjectProvider.getIfAvailable(fallback) - lazy retrieval with fallback
- Custom qualifiers (@Qualifier + meta-annotation) - type-safe, no strings
- Spring Boot FailureAnalyzer automatically shows all found beans on NoUniqueBeanDefinitionException
Common follow-up questions:
- What has priority: @Primary or @Qualifier? - @Qualifier, explicit choice always takes priority.
- How to implement Strategy pattern in Spring? - Map<String, Strategy> - key = bean name, selection at runtime without if/else.
- What happens if there is no @Primary, no @Qualifier, and no name match? - NoUniqueBeanDefinitionException.
- Why are custom qualifiers needed? - Type safety: compiler catches errors, no typos in strings.
Red flags (DO NOT say):
- “@Primary always overrides @Qualifier” - no, @Qualifier has highest priority.
- “Map injects only one bean” - no, Map contains ALL beans of the type, key = name.
- “It is fine to use strings in @Qualifier” - risky: typos caught only at runtime.
- “If there is @Primary, no other beans of this type exist” - no, all beans are registered, @Primary only selects default.
Related topics:
- [[28. What is Qualifier]]
- [[26. What does the Autowired annotation do]]
- [[24. What is a Configuration class]]
- [[25. Difference between Component Service Repository Controller]]