Що робить анотація @Autowired?
4. Уникайте static полів 5. Collection → усі біни типу 6. AOT → рефлексія замінюється на прямий код
🟢 Junior Level
@Autowired — вказує Spring впровадити залежність.
@Service
public class OrderService {
@Autowired // Spring сам знайде та впровадить OrderRepository
private OrderRepository repo;
}
Де працює:
- Конструктор
- Поля
- Сеттери
Правило:
- Один бін типу → впровадить його
- Кілька → помилка або @Qualifier
🟡 Middle Level
AutowiredAnnotationBeanPostProcessor
Обробка @Autowired:
1. Сканує поля/методи/конструктори
2. Створює InjectionMetadata (кеш)
3. Шукає підходящі біни
4. Впроваджує через рефлексію
Алгоритм пошуку
1. За типом (byType) — Spring знаходить усі біни цього типу
2. Якщо кілька — @Qualifier фільтрує за ім'ям
3. Якщо немає @Qualifier — перевіряється @Primary (глобальна мітка «за замовчуванням»)
4. Якщо немає @Primary — за ім'ям змінної (byName)
Constructor Injection (рекомендується)
@Service
public class OrderService {
private final OrderRepository repo;
// Один конструктор → @Autowired не потрібен!
public OrderService(OrderRepository repo) {
this.repo = repo;
}
}
Впровадження колекцій
// Усі біни типу PaymentService
@Autowired
List<PaymentService> payments;
// Map: ім'я біна → бін
@Autowired
Map<String, PaymentService> paymentMap;
🔴 Senior Level
ObjectProvider
@Autowired
ObjectProvider<PaymentService> provider;
// Ліниве отримання
PaymentService service = provider.getIfAvailable();
// Stream усіх бінів
provider.stream().forEach(...);
// Вирішення циклів!
Reflection Overhead
Field Injection → setAccessible(true) → рефлексія
→ + overhead при ініціалізації
Constructor Injection → прямий виклик
→ Швидше
AOT (GraalVM) → рефлексія → прямий код
→ Немає overhead від рефлексії (setAccessible). Залежності вирішуються на етапі компіляції.
Production Experience
Реальний сценарій: static поле
@Autowired
private static Repo repo; // НЕ працює!
// Spring впроваджує в екземпляри, не в класи
// → repo = null
Best Practices
- Constructor → за замовчуванням
- @Autowired не потрібен для одного конструктора
- ObjectProvider → для циклів та лінивості
- Уникайте static полів
- Collection → усі біни типу
- AOT → рефлексія замінюється на прямий код
Резюме для Senior
- AutowiredAnnotationBeanPostProcessor (AABPP) → обробка @Autowired
- Constructor → швидше, final поля
- ObjectProvider → ліниве, цикли
- static → не працює
- Collection → усі біни типу
- AOT → немає рефлексії в Native Image
🎯 Шпаргалка для інтерв’ю
Обов’язково знати:
- @Autowired обробляється AutowiredAnnotationBeanPostProcessor — сканує поля/методи/конструктори
- Алгоритм: byType → @Qualifier → @Primary → byName → помилка
- Constructor Injection — рекомендований підхід; з одним конструктором @Autowired не потрібен
- Впровадження колекцій: List
— усі біни типу, Map<String, T> — ім'я біна → бін - ObjectProvider — ліниве отримання, stream усіх бінів, вирішення циклічних залежностей
- @Autowired на static полях НЕ працює — Spring впроваджує в екземпляри, не в класи
- Constructor Injection швидший за Field Injection: прямий виклик vs рефлексія (setAccessible)
Часті уточнюючі запитання:
- Що буде, якщо два біни одного типу без @Qualifier? — NoUniqueBeanDefinitionException (якщо немає @Primary або збігу за ім’ям).
- Як вирішити циклічну залежність? — ObjectProvider.getIfAvailable() або setter/field injection замість constructor.
- Чому Constructor Injection рекомендується? — Immutable поля (final), немає рефлексії, легше тестувати, явні залежності.
- Чи працює @Autowired в GraalVM Native Image? — Так, але рефлексія замінюється на прямий код при AOT-компіляції.
Червоні прапорці (НЕ говорити):
- «@Autowired на static полі працює» — ні, Spring не впроваджує у статичні поля.
- «Spring шукає бін за ім’ям в першу чергу» — ні, спочатку byType, потім byName.
- «Field Injection краще Constructor Injection» — навпаки, constructor дає immutable та тестованість.
- «@Autowired завжди обов’язковий» — ні, з одним конструктором Spring впроваджує автоматично.
Пов’язані теми:
- [[27. Що робити, якщо є кілька бінів одного типу]]
- [[28. Що таке @Qualifier]]
- [[24. Що таке @Configuration клас]]
- [[25. В чому різниця між @Component, @Service, @Repository, @Controller]]