Ответ
Spring реализует принцип Inversion of Control (IoC) через свой центральный контейнер — ApplicationContext. Этот контейнер берет на себя управление жизненным циклом объектов (называемых бинами) и их зависимостями, что избавляет разработчика от необходимости создавать и связывать объекты вручную (например, через new).
Ключевой механизм — Dependency Injection (DI): Контейнер Spring автоматически внедряет зависимости в бины. Это можно делать тремя основными способами:
- Через конструктор (рекомендуемый способ).
- Через сеттер-методы.
- Через поля (с помощью
@Autowired).
Пример IoC/DI через конструктор:
// 1. Репозиторий — зависимость
@Repository
public class UserRepository {
// ... методы работы с БД
}
// 2. Сервис, которому нужен репозиторий
@Service
public class UserService {
private final UserRepository userRepository;
// 3. Контейнер Spring автоматически создаст UserRepository
// и передаст его в этот конструктор (Dependency Injection)
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUser(Long id) {
return userRepository.findById(id);
}
}
Преимущества такого подхода:
- Слабая связанность: компоненты не создают свои зависимости, а получают их извне.
- Упрощение тестирования: зависимости легко подменить моками в unit-тестах.
- Централизованная конфигурация: управление бинами и их скоупами (scope) происходит в одном месте.