Что такое @Qualifier?
4. Map → альтернатива для динамического выбора 5. Избегайте строк → опечатки 6. В Spring Boot 3+ (Jakarta EE) аннотация переехала из javax.inject в jakarta.inject. Функционально...
🟢 Junior Level
@Qualifier — уточняет, какой именно бин нужно внедрить.
// Два бина типа PaymentService
@Bean public PaymentService stripe() { ... }
@Bean public PaymentService paypal() { ... }
// Выбор через @Qualifier:
@Autowired
@Qualifier("stripe")
private PaymentService payment;
Зачем:
- Когда несколько бинов одного типа
- Чтобы точно указать нужный
🟡 Middle Level
Как работает
1. Spring находит все бины типа
2. Если есть @Qualifier → фильтрует по имени/аннотации
3. @Qualifier > @Primary по приоритету. @Qualifier — явное указание конкретного бина,
Spring рассматривает его как более точное. @Primary — глобальная метка «по умолчанию».
Явный выбор всегда приоритнее.
На @Bean методах
@Configuration
public class Config {
@Bean
@Qualifier("fast")
public RestTemplate fastRestTemplate() { ... }
@Bean
@Qualifier("slow")
public RestTemplate slowRestTemplate() { ... }
}
Кастомные квалификаторы
@Qualifier // ← Мета-аннотация!
@Retention(RUNTIME)
public @interface FastService { }
@FastService
@Bean
public Service fastService() { ... }
@Autowired
@FastService
private Service service;
// → Типобезопасно, нет строк!
🔴 Senior Level
Приоритет
@Qualifier > @Primary > byName > @Priority
→ Если есть @Qualifier → @Primary игнорируется!
С параметрами
@Qualifier
@Retention(RUNTIME)
public @interface Database {
String value() default "postgres";
boolean readOnly() default false;
}
// Spring сопоставляет ВСЕ атрибуты!
@Database(value = "postgres", readOnly = true)
@Bean
public DataSource readOnlyDb() { ... }
ObjectProvider ограничение
// Программный выбор квалификатора затруднён
// Решение: Map<String, T>
@Autowired
Map<String, Service> services;
Service service = services.get("fast");
Production Experience
Реальный сценарий: опечатка в строке
@Qualifier("fastService") // Забыли "s"
→ NoSuchBeanDefinitionException
Решение: кастомные аннотации
→ Компилятор ловит ошибки
Best Practices
- Кастомные аннотации → типобезопасно
- @Qualifier > @Primary → приоритет
- На @Bean методах → для нескольких бинов
- Map → альтернатива для динамического выбора
- Избегайте строк → опечатки
- В Spring Boot 3+ (Jakarta EE) аннотация переехала из
javax.injectвjakarta.inject. Функциональность та же.
Резюме для Senior
- @Qualifier → уточнение выбора
- @Qualifier > @Primary → приоритет
- Кастомные аннотации → типобезопасно
- Атрибуты → тонкая настройка
- Map → динамический выбор
- Избегайте строк → опечатки
🎯 Шпаргалка для интервью
Обязательно знать:
- @Qualifier уточняет, какой именно бин внедрить, когда их несколько одного типа
- Приоритет: @Qualifier > @Primary > byName > @Priority
- @Qualifier ставится на @Bean методы и на точки инъекции (@Autowired, конструктор)
- Кастомные квалификаторы: @Qualifier как мета-аннотация → типобезопасность, нет строк-опечаток
- Кастомные квалификаторы с атрибутами: Spring сопоставляет ВСЕ атрибуты аннотации
- В Spring Boot 3+ (Jakarta EE) @Qualifier переехал из javax.inject в jakarta.inject
- Map<String, T> — альтернатива для динамического выбора без @Qualifier
Частые уточняющие вопросы:
- Что важнее: @Qualifier или @Primary? — @Qualifier всегда приоритетнее; при наличии @Qualifier @Primary игнорируется.
- Почему кастомные квалификаторы лучше строк? — Компилятор проверяет типы; опечатки в строках ловятся только в рантайме.
- Можно ли использовать @Qualifier с атрибутами? — Да, Spring сопоставляет все атрибуты кастомной аннотации-квалификатора.
- Что будет при опечатке в строке @Qualifier? — NoSuchBeanDefinitionException — бин с таким именем не найден.
Красные флаги (НЕ говорить):
- «@Primary переопределяет @Qualifier» — нет, @Qualifier всегда приоритетнее.
- «@Qualifier ищет бин по типу» — нет, @Qualifier фильтрует по имени/аннотации среди бинов одного типа.
- «Строки в @Qualifier — лучшая практика» — нет, кастомные аннотации типобезопаснее.
- «@Qualifier работает только с @Autowired» — нет, также на @Inject, @Bean, параметрах конструктора.
Связанные темы:
- [[27. Что делать, если есть несколько бинов одного типа]]
- [[26. Что делает аннотация @Autowired]]
- [[24. Что такое @Configuration класс]]
- [[25. В чём разница между @Component, @Service, @Repository, @Controller]]