Объясните принцип внедрения зависимостей (Dependency Injection, DI).

«Объясните принцип внедрения зависимостей (Dependency Injection, DI).» — вопрос из категории Spring, который задают на 27% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Внедрение зависимостей (DI) — это паттерн проектирования, при котором объект получает свои зависимости извне, а не создает их самостоятельно. Это реализация принципа Inversion of Control (IoC).

Суть: Класс не должен жестко создавать (new) объекты, от которых он зависит. Вместо этого зависимости "внедряются" в него, обычно через конструктор, сеттер или поле.

Пример без DI (проблема):

public class OrderService {
    // Прямое создание зависимости - сильная связанность
    private PaymentProcessor processor = new PayPalProcessor();
    // Тестировать OrderService в изоляции сложно
}

Пример с DI (решение):

public class OrderService {
    private final PaymentProcessor processor;
    // Зависимость внедряется через конструктор
    public OrderService(PaymentProcessor processor) {
        this.processor = processor;
    }
    public void processOrder(Order order) {
        processor.charge(order.getAmount());
    }
}
// Теперь можно легко подменить реализацию для тестов
OrderService serviceWithMock = new OrderService(mockProcessor);
OrderService serviceWithReal = new OrderService(new StripeProcessor());

Преимущества DI:

  • Слабая связанность: Классы зависят от абстракций (интерфейсов), а не от конкретных реализаций.
  • Упрощение тестирования: Легко подменять реальные зависимости mock-объектами в unit-тестах.
  • Гибкость конфигурации: Поведение приложения можно менять, не изменяя код основных классов.
  • Повторное использование кода: Компоненты становятся более независимыми и пригодными для использования в других контекстах.

В Spring DI является краеугольным камнем. Контейнер Spring (ApplicationContext) автоматически создает и связывает бины (объекты), управляя их жизненным циклом.