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

Инъекция конструктора весной с Ломбоком

Быстрый и практический пример инъекции конструктора с Ломбоком весной

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

1. введение

Ломбок-это чрезвычайно полезная библиотека, позволяющая преодолевать шаблонный код. Если вы еще не знакомы с ним, я настоятельно рекомендую взглянуть на предыдущий учебник – Введение в проект Ломбок .

В этой статье мы продемонстрируем его удобство использования в сочетании с внедрением зависимостей на основе конструктора Spring .

2. Внедрение Зависимостей На Основе Конструктора

Хороший способ связать зависимости весной с помощью c инъекции зависимостей на основе конструктора . Этот подход заставляет нас явно передавать зависимости компонентов конструктору.

В отличие от Внедрения зависимостей на основе полей , он также обеспечивает ряд преимуществ:

  • нет необходимости создавать компонент конфигурации для конкретного теста-зависимости вводятся явно в конструктор
  • согласованный дизайн – все необходимые зависимости подчеркиваются и обрабатываются определением конструктора
  • простые модульные тесты – снижение накладных расходов Spring Framework
  • восстановленная свобода использования окончательные ключевые слова

Однако из-за необходимости написания конструктора он используется для создания значительно большей базы кода. Рассмотрим два примера Службы приветствия и Прощальной службы:

@Component
public class GreetingService {

    @Autowired
    private Translator translator;

    public String produce() {
        return translator.translate("hello");
    }
}
@Component
public class FarewellService {

    private final Translator translator;

    public FarewellService(Translator translator) {
        this.translator = translator;
    }

    public String produce() {
        return translator.translate("bye");
    }
}

В принципе, оба компонента делают одно и то же – они вызывают настраиваемый Переводчик с конкретным словом задачи.

Второй вариант, однако, гораздо более запутан из-за шаблона конструктора, который на самом деле не приносит никакого значения коду.

В новейшем весеннем выпуске его конструктор не нуждается в аннотации @Autowired аннотация.

3. Инъекция Конструктора С Ломбоком

С помощью Lombok можно создать конструктор либо для всех полей класса (с помощью @AllArgsConstructor ), либо для всех полей final класса (с помощью @RequiredArgsConstructor ). Кроме того, если вам все еще нужен пустой конструктор, вы можете добавить дополнительную аннотацию @NoArgsConstructor .

Давайте создадим третий компонент, аналогичный двум предыдущим:

@Component
@RequiredArgsConstructor
public class ThankingService {

    private final Translator translator;

    public String produce() {
        return translator.translate("thank you");
    }
}

Приведенная выше аннотация приведет к тому, что Lombok создаст для нас конструктор:

@Component
public class ThankingService {

    private final Translator translator;

    public String thank() {
        return translator.translate("thank you");
    }

    /* Generated by Lombok */
    public ThankingService(Translator translator) {
        this.translator = translator;
    }
}

4. Несколько Конструкторов

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

Рассмотрим пример Службы извинений :

@Component
@RequiredArgsConstructor
public class ApologizeService {

    private final Translator translator;
    private final String message;

    @Autowired
    public ApologizeService(Translator translator) {
        this(translator, "sorry");
    }

    public String produce() {
        return translator.translate(message);
    }
}

Вышеуказанный компонент дополнительно настраивается с помощью поля message , которое не может измениться после создания компонента (отсюда отсутствие setter ). Таким образом, нам потребовалось предоставить два конструктора – один с полной конфигурацией, а другой с неявным значением по умолчанию message .

Если один из конструкторов не аннотирован либо @Autowired , @Inject или @Resource , Spring выдаст ошибку:

Failed to instantiate [...]: No default constructor found;

Если бы мы хотели аннотировать Lombok- сгенерированный конструктор, нам пришлось бы передать аннотацию с параметром on конструктора конструктора @AllArgsConstructor :

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ApologizeService {
    // ...
}

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

Причина странного синтаксиса заключается в том, чтобы заставить эту функцию работать в компиляторах javac 7; тип @__ является ссылкой аннотации на тип аннотации __ (двойное подчеркивание), который на самом деле не существует; это заставляет javac 7 задерживать прерывание процесса компиляции из-за ошибки, поскольку возможно, что процессор аннотаций позже создаст тип __|/.

5. Резюме

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

Благодаря Lombok можно автоматизировать генерацию общего кода без влияния на производительность во время выполнения, сокращая длинный, затемняющий код до использования однострочной аннотации.

Код, используемый во время урока, доступен на GitHub .