Ответ
Внедрение через конструктор (Constructor Injection) — это рекомендуемый best practice в Spring.
Пример реализации:
@Service
public class UserService {
private final UserRepository userRepository;
// Начиная с Spring 4.3, аннотация @Autowired для конструктора с одним параметром не обязательна
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Почему это лучший способ:
- Неизменяемость (Immutability): Поля можно объявить как
final, гарантируя их инициализацию только один раз. - Явность зависимостей: Все зависимости видны в сигнатуре конструктора, что упрощает понимание класса.
- Упрощение тестирования: Зависимости легко передать в конструктор при unit-тестировании без необходимости Spring-контекста.
- Безопасность от NPE: Объект не может быть создан в неполностью инициализированном состоянии.
Альтернативные (менее предпочтительные) способы:
- Внедрение через поле (Field Injection): Не рекомендуется из-за сложности тестирования и скрытых зависимостей.
- Внедрение через сеттер (Setter Injection): Подходит для опциональных зависимостей, которые могут меняться в runtime.