Ответ
Использование инъекции через конструктор предпочтительнее полевой инъекции (@Autowired над полем) по следующим причинам:
- Неизменяемость (Immutability): Поля зависимостей можно объявить как
final. Это гарантирует их обязательную инициализацию при создании бина и защищает от случайного изменения после инъекции. - Явное объявление зависимостей: Все зависимости видны в конструкторе, что делает контракт класса понятным и упрощает обнаружение проблем с циклическими зависимостями на этапе компиляции.
- Упрощение тестирования: Класс можно легко протестировать без Spring Context, просто создав экземпляр через
newи передав моки зависимостей в конструктор. - Отказоустойчивость: Приложение не запустится, если какая-либо зависимость, требуемая в конструкторе, не найдена в контексте. Полевая инъекция может привести к
NullPointerExceptionво время выполнения.
Пример лучшей практики:
@Service
public class OrderService {
// Поле final - зависимость обязательна и неизменна
private final OrderRepository orderRepository;
private final NotificationService notificationService;
// Один конструктор: @Autowired опционален в Spring 4.3+
public OrderService(OrderRepository orderRepository,
NotificationService notificationService) {
this.orderRepository = orderRepository;
this.notificationService = notificationService;
}
public void placeOrder(Order order) {
orderRepository.save(order);
notificationService.sendConfirmation(order);
}
}
Для теста не нужен Spring:
@Test
void placeOrder_ShouldSaveAndNotify() {
// Arrange
OrderRepository repoMock = mock(OrderRepository.class);
NotificationService notifMock = mock(NotificationService.class);
OrderService service = new OrderService(repoMock, notifMock); // Просто new
Order testOrder = new Order();
// Act & Assert
service.placeOrder(testOrder);
verify(repoMock).save(testOrder);
verify(notifMock).sendConfirmation(testOrder);
}
Когда полевая инъекция допустима? В основном в конфигурационных классах или простых компонентах без логики (например, @Controller в Spring MVC), но даже там конструктор предпочтительнее.