Що таке @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]]