Что такое Dependency Injection (DI) в Spring Framework?

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

Ответ

Dependency Injection (DI, Внедрение зависимостей) — это основополагающий принцип Spring Framework, при котором зависимости объекта (другие объекты, которые ему нужны для работы) предоставляются ему извне, а не создаются внутри самого объекта. Управление этими зависимостями и жизненным циклом объектов (бинов) осуществляет IoC-контейнер Spring.

Зачем это нужно? DI снижает связность компонентов, упрощает тестирование и делает код более модульным.

Основные способы внедрения в Spring:

  1. Внедрение через конструктор (Constructor Injection) — рекомендуется.

    @Service
    public class OrderService {
        private final PaymentProcessor paymentProcessor;
    
        // Контейнер Spring автоматически найдет и внедрит подходящий бин
        @Autowired // Необязательно с Spring 4.3+, если конструктор один
        public OrderService(PaymentProcessor paymentProcessor) {
            this.paymentProcessor = paymentProcessor;
        }
    }
    • Преимущества: Зависимости явно объявлены, объект создается в валидном состоянии, поле можно сделать final (неизменяемым).
  2. Внедрение через сеттер (Setter Injection).

    @Component
    public class UserService {
        private UserRepository repository;
    
        @Autowired
        public void setRepository(UserRepository repository) {
            this.repository = repository;
        }
    }
  3. Внедрение через поле (Field Injection) — не рекомендуется для production-кода.

    @Repository
    public class UserRepositoryImpl {
        @Autowired
        private DataSource dataSource; // Прямое внедрение в поле
    }
    • Недостатки: Усложняет тестирование (нужен контейнер или рефлексия), скрывает зависимости, нельзя сделать поле final.

Ключевые аннотации: @Component, @Service, @Repository, @Controller (для объявления бинов) и @Autowired (для указания точек внедрения).