Рубрики
Без рубрики

Внедрение зависимостей конструктора весной

Быстрое и практичное введение в инъекцию на основе конструктора с пружиной.

Автор оригинала: baeldung.

1. введение

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

В этой статье будет рассмотрен конкретный тип метода DI, называемый Инъекцией зависимостей на основе конструктора в Spring, что, проще говоря, означает, что необходимые компоненты передаются в класс во время создания экземпляра.

Для начала нам нужно импортировать spring-контекст зависимость в ваш pom.xml :


    org.springframework
    spring-context
    5.2.8.RELEASE

Затем нам нужно настроить файл Конфигурация . Этот файл может быть либо POJO, либо, если вы предпочитаете, XML-файлом.

Дальнейшее чтение:

Введение в инверсию управления и внедрение зависимостей с помощью пружины

Лучшие Вопросы для интервью в рамках Весеннего Фреймворка

Проводка весной: @Autowired, @Resource и @Inject

2. Конфигурация на Основе аннотаций

Файл конфигурации Java выглядит в значительной степени как обычный старый объект Java с некоторыми дополнительными аннотациями:

@Configuration
@ComponentScan("com.baeldung.constructordi")
public class Config {

    @Bean
    public Engine engine() {
        return new Engine("v8", 5);
    }

    @Bean
    public Transmission transmission() {
        return new Transmission("sliding");
    }
}

Здесь мы используем аннотации, чтобы уведомить Spring runtime о том, что этот класс является поставщиком определений компонентов ( @Bean аннотация) и что в пакете com.baeldung.spring необходимо выполнить проверку контекста на наличие дополнительных компонентов . Далее мы определяем Класс автомобиля :

@Component
public class Car {

    @Autowired
    public Car(Engine engine, Transmission transmission) {
        this.engine = engine;
        this.transmission = transmission;
    }
}

Spring столкнется с нашим классом Car во время сканирования пакета и инициализирует его экземпляр, вызвав @Autowired аннотированный конструктор.

Экземпляры Двигателя и трансмиссии будут получены путем вызова @Bean аннотированных методов класса Config . Наконец, нам нужно загрузить ApplicationContext , используя нашу конфигурацию POJO:

ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Car car = context.getBean(Car.class);

3. Неявная Инъекция Конструктора

Начиная с весны 4.3, классы с одним конструктором могут опускать аннотацию @Autowired . Приятная мелочь для удобства и удаления шаблонов!

Кроме того, начиная с версии 4.3, внедрение на основе конструктора может быть использовано в @Configuration аннотированных классах. И да, если у такого класса есть только один конструктор, аннотацию @Autowired также можно опустить.

4. Конфигурация на основе XML

Другой способ настроить среду выполнения Spring с помощью внедрения зависимостей на основе конструктора-использовать файл конфигурации XML:


    
    



    
    



    

Обратите внимание, что конструктор-arg может принимать буквальное значение или ссылку на другой компонент и что может быть предоставлен необязательный явный индекс и тип . Тип и индекс атрибуты могут использоваться для устранения неоднозначности (например, если конструктор принимает несколько аргументов одного и того же типа).

имя атрибут также может использоваться для сопоставления переменных xml и java, но тогда ваш код должен быть скомпилирован с включенным флагом отладки.

Контекст приложения Spring в этом случае необходимо загрузить с помощью ClassPathXmlApplicationContext :

ApplicationContext context = new ClassPathXmlApplicationContext("baeldung.xml");
Car car = context.getBean(Car.class);

5. Плюсы и минусы

Инъекция конструктора имеет несколько преимуществ по сравнению с инъекцией в полевых условиях.

Первое преимущество-это проверяемость. Предположим, мы собираемся провести модульное тестирование пружинного компонента, который использует инъекцию поля:

public class UserService {
    
    @Autowired 
    private UserRepository userRepository;
}

Во время создания экземпляра UserService мы не можем инициализировать состояние UserRepository . Единственный способ достичь этого-через API отражения , который полностью нарушает инкапсуляцию. Кроме того, полученный код будет менее безопасным по сравнению с простым вызовом конструктора.

Кроме того, с инъекцией поля мы не можем применять инварианты уровня класса. Таким образом, возможно иметь экземпляр UserService без правильно инициализированного UserRepository . Поэтому мы можем столкнуться со случайным NullPointerException здесь и там. Кроме того, с помощью инъекции конструктора проще создавать неизменяемые компоненты.

Более того, использование конструкторов для создания экземпляров объектов более естественно с точки зрения ООП.

С другой стороны, основным недостатком внедрения конструктора является его многословие, особенно когда компонент имеет несколько зависимостей. Иногда это может быть скрытым благословением, так как мы можем изо всех сил стараться свести количество зависимостей к минимуму.

6. Заключение

Этот краткий учебник продемонстрировал основы двух различных способов использования Инъекции зависимостей на основе конструктора с использованием фреймворка Spring.

Полную реализацию этого руководства можно найти на GitHub .