junior
Как работает @Autowired? Какие существуют способы внедрения зависимостей?
@Autowired – аннотация Spring, которая автоматически внедряет зависимости по типу (by type). Если найден ровно один бин подходящего типа, он будет внедрён.
Три способа внедрения зависимостей
| Способ | Рекомендация | Причина |
|---|---|---|
| Через конструктор | Рекомендуется | Неизменяемость (final), обязательность, тестируемость без рефлексии |
| Через сеттер | Допустимо | Для необязательных зависимостей |
| Через поле | Не рекомендуется | Скрывает зависимости, требует рефлексии для тестов |
Пример
// 1. Через конструктор (рекомендуемый)
@Service
public class UserService {
private final UserRepository userRepository;
// С Spring 4.3 @Autowired можно не указывать при одном конструкторе
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// 2. Через сеттер
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
// 3. Через поле (не рекомендуется)
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
}
Порядок разрешения зависимостей
- Ищет бин по типу
- Если найдено несколько – ищет по имени поля/параметра
- Если не найден –
NoSuchBeanDefinitionException - Если найдено несколько и имя не совпадает –
NoUniqueBeanDefinitionException
На собеседовании: интервьюер ждёт обоснование, почему конструкторное внедрение лучше: immutability, обязательность, тестируемость, видимость нарушений SRP. Частая ошибка – не знать про циклические зависимости и способы их решения (
@Lazy, рефакторинг).