IoC-контейнер
IoC (Inversion of Control) — переворот ответственности: не твой код создаёт объекты, а специальный контейнер создаёт их за тебя и сам решает, кому что передать. Это прямое применение принципа Dependency Inversion из SOLID (см. тему «O, L, I, D»).
// Без Spring — ты сам создаёшь и связываешь объекты
OrderRepository repo = new OrderRepository();
OrderService service = new OrderService(repo);
// Со Spring — контейнер делает это сам
@Service
class OrderService {
private final OrderRepository repo;
OrderService(OrderRepository repo) { this.repo = repo; } // Spring сам подставит готовый repo
}
Spring сканирует классы, находит помеченные аннотациями (@Service, @Repository), создаёт их объекты (бины) и сам разбирается, какой объект какому нужен — это и называется внедрение зависимостей (Dependency Injection).
Копнуть глубже
Контейнер (ApplicationContext) — это хранилище всех бинов приложения. При старте приложения Spring:
- Сканирует пакеты в поиске классов с аннотациями
@Component/@Service/@Repository/@Controller; - Создаёт объекты этих классов (бины);
- Анализирует, какие зависимости нужны каждому бину (через конструктор);
- Связывает их между собой в правильном порядке.
Зачем это вообще нужно, а не просто new вручную. Без IoC каждый класс сам отвечает за создание своих зависимостей — это сильно связывает классы между собой и усложняет тестирование (нельзя подменить реальную зависимость на mock без изменения кода создания объекта). С IoC зависимости подставляются снаружи — легко подменить на тестовый mock (см. тему «Mockito»), легко поменять реализацию, не трогая зависимый класс.
• что делает ApplicationContext при старте приложения (если дошёл до 2-го слоя).