Что делает аннотация @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]]