Короткий ответ
Autowiring — механизм автоматического связывания бинов, который выполняет контейнер Spring, обычно по аннотации @Autowired; он избавляет от ручной настройки связей и способствует слабой связанности. Выделяют три способа внедрения: через конструктор, через сеттер и напрямую в поле класса.
Как это работает подробнее
Рекомендуемый подход — конструкторная инъекция, особенно для обязательных зависимостей: объект создаётся полностью инициализированным, зависимости нельзя поменять после создания, исключается частично инициализированное состояние и связанные с ним ошибки, а класс легко тестировать, передавая моки в конструктор.
- Сеттерная инъекция уместна для опциональных зависимостей, которые могут меняться в процессе жизни объекта.
- Инъекция в поле через
@Autowiredпроста в написании, но скрывает зависимости, мешает тестированию (сложно подставить мок без контейнера) и нарушает неизменяемость. - Важный нюанс: если у бина один конструктор, явная
@Autowiredна нём не обязательна — контейнер использует его сам.
Пример кода
NotifierService.java
@Component
public class NotifierService {
// 1) инъекция в поле
@Autowired
private SmsNotifier smsNotifier;
private EmailNotifier emailNotifier;
// 2) сеттерная инъекция
@Autowired
public void setEmailNotifier(EmailNotifier emailNotifier) {
this.emailNotifier = emailNotifier;
}
private final PushNotifier pushNotifier;
// 3) конструкторная инъекция
public NotifierService(PushNotifier pushNotifier) {
this.pushNotifier = pushNotifier;
}
}Что использовать на практике
- Отдавайте предпочтение конструкторной инъекции с final-полями: она даёт неизменяемость, полноту инициализации и удобное тестирование.
- Сеттерную инъекцию применяйте только для опциональных зависимостей.
- Field-инъекции через
@Autowiredв новом коде избегайте.
Подводные камни
- Если у бина несколько конструкторов, нужный нужно явно пометить
@Autowired, иначе контейнер не поймёт, какой использовать. - Инъекция в поле не сработает для объекта, созданного через
new: контейнер не участвует в его создании и не внедрит зависимости.
Как отвечать на собеседовании
- Определите autowiring как автоматическое внедрение зависимостей контейнером → назовите три способа: конструктор, сеттер, поле → объясните, почему конструкторная инъекция предпочтительна (неизменяемость, полная инициализация, тестируемость) → упомяните нюанс: при одном конструкторе
@Autowiredне нужна.