Проверяет понимание принципов DI, преимуществ иммутабельности и тестируемости кода.
Внедрение через конструктор делает зависимости явными, класс — иммутабельным и упрощает тестирование. @Autowired в поле скрывает зависимости, усложняет мокирование и может привести к NullPointerException, если Spring не инициализирует поле.
Проблемы @Autowired в поле:
Скрытые зависимости: Класс не сигнализирует, что ему нужны зависимости (нет конструктора/сеттеров).
Тестирование: Требует Spring-контекста или рефлексии для внедрения моков.
Иммутабельность: Поля можно менять после создания, что рискованно в многопоточке.
Преимущества конструктора (@RequiredArgsConstructor):
@Service
@RequiredArgsConstructor // Генерирует конструктор с final-полями
public class BookService {
private final BookRepository bookRepository; // Зависимость явная и неизменяемая
public Book findById(Long id) {
return bookRepository.findById(id).orElseThrow();
}
}Тестирование без Spring:
@Test
void findByIdTest() {
BookRepository mockRepo = mock(BookRepository.class);
BookService service = new BookService(mockRepo); // Простое создание
// ... тест
}Безопасность: Зависимости инициализируются один раз при создании объекта.
Вывод: Всегда используйте внедрение через конструктор для обязательных зависимостей.