«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Исследование синтетических бобов в Quarkus. Мощный механизм расширения

Исследование синтетических бобов в Quarkus. Мощный механизм расширения

Опубликовано 2 сентября 2024 г.
Просматривать:688

Exploring Synthetic Beans in Quarkus. A Powerful Extension Mechanism

В мире Quarkus сфера внедрения зависимостей богата и универсальна, предлагая разработчикам множество инструментов для управления компонентами и контроля над ними. Одним из таких инструментов является концепция синтетических бобов. Синтетические bean-компоненты — это мощный механизм расширения, который позволяет регистрировать bean-компоненты, атрибуты которых не являются производными от класса, метода или поля Java. Вместо этого все атрибуты синтетического компонента определяются расширением.

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

Понимание синтетических бобов

В Quarkus bean-компоненты — это строительные блоки вашего приложения, управляемые платформой внедрения контекстов и зависимостей (CDI). Обычно компоненты CDI представляют собой классы Java, помеченные различными аннотациями CDI, такими как @ApplicationScoped, @RequestScoped или @Inject. Эти аннотации
позволить CDI автоматически управлять жизненным циклом и внедрением компонентов.

Однако бывают ситуации, когда вам может потребоваться зарегистрировать компонент, который не совсем вписывается в традиционную модель CDI. Именно здесь в игру вступают синтетические бобы. Синтетические bean-компоненты создаются расширениями, и их атрибуты полностью определяются этими расширениями. В мире обычного CDI этого можно добиться с помощью методов AfterBeanDiscovery.addBean() и SyntheticComponents.addBean(). В Quarkus это достигается с помощью SyntheticBeanBuildItem.

Когда вам нужны синтетические бобы?

Итак, когда вам может понадобиться использовать синтетические компоненты в Quarkus? Синтетические бобы являются мощным инструментом, когда:

  1. Интеграция сторонних библиотек: Вы работаете со сторонней библиотекой, которая не имеет аннотаций CDI, но должна быть интегрирована в ваше приложение на основе CDI. Синтетические бобы позволяют восполнить этот пробел.

  2. Динамическая регистрация компонентов: Вам необходимо регистрировать компоненты динамически во время выполнения, в зависимости от конфигурации или других факторов. Синтетические bean-компоненты дают вам возможность создавать и регистрировать bean-компоненты «на лету».

  3. Настраиваемое управление компонентами: Вам требуется детальный контроль над областью действия и поведением компонента, которого невозможно достичь с помощью стандартных аннотаций CDI.

  4. Реализация специализированных компонентов: Вы хотите создать специализированные компоненты с уникальными атрибутами, которые не соответствуют традиционным классам или методам Java.

  5. Имитация зависимостей для тестирования: Синтетические bean-компоненты предоставляют полезный способ макетирования зависимостей и внедрения макетных реализаций для целей тестирования.

СинтезFinishedBuildItem

SynthesisFinishedBuildItem используется для указания того, что процесс обнаружения и регистрации компонента CDI завершен. Это позволяет расширениям знать, когда безопасно взаимодействовать с зарегистрированными компонентами.

Например:

@BuildStep  
void onSynthesisFinished(SynthesisFinishedBuildItem synthesisFinished){
    // CDI bean registration is complete, can now safely interact with beans
    }

SyntheticBeansRuntimeInitBuildItem

SyntheticBeansRuntimeInitBuildItem используется для регистрации обратного вызова, который будет вызываться во время выполнения после инициализации всех синтетических компонентов. Это полезно, если вам нужно выполнить дополнительную логику инициализации с использованием синтетических bean-компонентов.

Например:

@BuildStep
SyntheticBeansRuntimeInitBuildItem initSyntheticBeans(){

    return new SyntheticBeansRuntimeInitBuildItem(ids->{
    // Perform logic with initialized synthetic beans
    });

    }

Обратный вызов, переданный в SyntheticBeansRuntimeInitBuildItem, получит Set, содержащий идентификаторы всех инициализированных синтетических bean-компонентов.

Итак, SynthesisFinishedBuildItem указывает на то, что обнаружение bean-компонентов завершено, а SyntheticBeansRuntimeInitBuildItem позволяет инициализировать логику в зависимости от синтетических bean-компонентов.

Создание синтетических компонентов с помощью SyntheticBeanBuildItem

В Quarkus создание синтетических bean-компонентов представляет собой простой процесс благодаря классу SyntheticBeanBuildItem. Давайте пройдемся по шагам по созданию и использованию синтетического компонента:

  1. Создайте класс синтетического компонента: Начните с определения класса синтетического компонента. Этот класс станет основой вашего синтетического компонента.
package com.iqnev;

public class MySyntheticBean {

  // Define the behavior and attributes of your synthetic bean
  public void printMessage() {
    System.out.println("Hello from synthetic bean!");
  }
}
  1. Создайте расширение Quarkus: Вам потребуется создать расширение Quarkus, чтобы зарегистрировать синтетический компонент. Этот класс расширения будет использовать SyntheticBeanBuildItem для настройки вашего bean-компонента.

Подход к генерации байт-кода

package com.iqnev;

import io.quarkus.arc.deployment.SyntheticBeanBuildItem;

public class MySyntheticBeanExtension {

  @BuildStep
  SyntheticBeanBuildItem syntheticBean() {
    return SyntheticBeanBuildItem
        .configure(MySyntheticBean.class)
        .scope(ApplicationScoped.class)
        .creator(mc -> {
          mc.returnValue(new MySyntheticBean());
        })
        .done();
  }
}

Метод .creator() в SyntheticBeanBuildItem используется для генерации байт-кода, который будет создавать экземпляры синтетического компонента во время выполнения.

Аргумент, передаваемый в .creator(), является Consumer, который позволяет генерировать байт-код Java внутри метода.

В этом примере:

  1. mc — экземпляр MethodCreator
  2. mc.returnValue(new MySyntheticBean()) генерирует байт-код для создания нового экземпляра MySyntheticBean и возвращает его из метода.

По сути, мы говорим Quarkus сгенерировать метод, который выглядит примерно так:

MySyntheticBean createSyntheticBean(){
    return new MySyntheticBean();
    }

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

Причина использования генерации байт-кода заключается в том, что синтетические bean-компоненты не соответствуют реальным классам/методам Java, поэтому нам необходимо явно сгенерировать метод для их создания экземпляров

Выходные данные SyntheticBeanBuildItem — это байт-код, записанный во время сборки. Это ограничивает способ создания экземпляров во время выполнения. Общие параметры:

  1. Сгенерировать байт-код напрямую через .creator()
  2. Использовать подкласс BeanCreator
  3. Создать экземпляр с помощью метода @Recorder

Подход к регистратору

Подходы @Record и .runtimeValue() — это альтернативные способы предоставления экземпляров синтетических bean-компонентов в Quarkus.

Это позволяет вам создать экземпляр синтетического bean-компонента с помощью метода класса рекордера, аннотированного @Record(STATIC_INIT).

Например:

@Recorder
public class MyRecorder {

  @Record(STATIC_INIT)
  public MySyntheticBean createBean() {
    return new MySyntheticBean();
  }

}

  @BuildStep
  SyntheticBeanBuildItem syntheticBean(MyRecorder recorder) {
    return SyntheticBeanBuildItem
        .configure(MySyntheticBean.class)
        .runtimeValue(recorder.createBean());
  }

Здесь .runtimeValue() ссылается на метод записи для создания экземпляра компонента. Это позволяет напрямую передать RuntimeValue для предоставления экземпляра синтетического компонента.

Например:

@BuildStep 
SyntheticBeanBuildItem syntheticBean(){

    RuntimeValue bean= //...

    return SyntheticBeanBuildItem
    .configure(MySyntheticBean.class)
    .runtimeValue(bean);

    }

Значение RuntimeValue может исходить от записывающего устройства, поставщика, прокси-сервера и т. д.

Итак, вкратце:

  • @Record — это один из способов создания RuntimeValue.
  • .runtimeValue() устанавливает RuntimeValue для SyntheticBeanBuildItem.

Они оба достигают одной и той же цели — предоставления экземпляра среды выполнения, только немного разными способами.

Когда дело доходит до предоставления экземпляров времени выполнения синтетических bean-компонентов в Quarkus, я бы рассматривал использование устройств записи (через @Record) как более продвинутый подход по сравнению с прямой генерацией байт-кода
с помощью .creator() или предоставления простых RuntimeValues.

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

  • Большая инкапсуляция - Логика создания экземпляров bean-компонентов содержится в отдельном классе рекордера, а не непосредственно на этапах сборки. Это позволяет сократить этапы сборки.
  • Повторное использование - Методы рекордера можно повторно использовать в нескольких синтетических компонентах, а не переписывать логику создателя.
  • Данные времени выполнения — Методы записи выполняются во время выполнения, поэтому они могут использовать ресурсы времени выполнения, конфигурации, службы и т. д. для создания bean-компонентов.
  • Внедрение зависимостей - Методы рекордера могут внедрять другие сервисы.
  • Управление жизненным циклом - Методы записи, аннотированные @Record(STATIC_INIT) или @Record(RUNTIME_INIT), дают больший контроль над жизненным циклом создания экземпляра компонента.
  • Управляемые компоненты - Компоненты, экземпляры которых создаются внутри устройств записи, сами могут быть управляемыми компонентами CDI.

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

Однако прямая генерация байт-кода с помощью .creator() может быть полезна в простых случаях, когда средства записи могут оказаться излишними. Но по мере роста потребностей в синтетических компонентах устройства записи становятся более мощными и
продвинутый подход.

В Quarkus можно настроить синтетический компонент для инициализации во время фазы RUNTIME_INIT вместо фазы STATIC_INIT по умолчанию.

Вот пример:

@BuildStep
@Record(RUNTIME_INIT)
SyntheticBeanBuildItem lazyBean(BeanRecorder recorder){

    return SyntheticBeanBuildItem
    .configure(MyLazyBean.class)
    .setRuntimeInit() // initialize during RUNTIME_INIT
    .runtimeValue(recorder.createLazyBean());

    }

Ключевые моменты:

  • Используйте setRuntimeInit() для SyntheticBeanBuildItem, чтобы пометить его как RUNTIME_INIT
  • Метод записи должен быть помечен @Record(RUNTIME_INIT)
  • Синтетические bean-компоненты инициализации среды выполнения недоступны во время STATIC_INIT

Итак, синтетические bean-компоненты можно инициализировать лениво во время RUNTIME_INIT в тех случаях, когда активное создание экземпляра STATIC_INIT не требуется. Это позволяет оптимизировать время запуска.

Используйте синтетический компонент: Теперь, когда ваш синтетический компонент зарегистрирован, вы можете внедрить его и использовать в своем приложении.

package com.iqnev;

import javax.inject.Inject;

public class MyBeanUser {

  @Inject
  MySyntheticBean mySyntheticBean;

  public void useSyntheticBean() {
    // Use the synthetic bean in your code
    mySyntheticBean.printMessage();
  }
}

Запуск приложения: Создайте и запустите приложение Quarkus как обычно, и синтетический компонент будет доступен для внедрения и использования.

Заключение

Синтетические bean-компоненты в Quarkus предоставляют мощный механизм для интеграции внешних библиотек, динамической регистрации bean-компонентов и настройки поведения bean-компонентов в ваших приложениях на основе CDI. Эти bean-компоненты, атрибуты которых определяются расширениями, а не классами Java, предлагают гибкость и универсальность в управлении зависимостями.

Как мы рассмотрели в этой статье, создание и использование синтетических компонентов в Quarkus — это простой процесс. Используя расширения SyntheticBeanBuildItem и Quarkus, вы можете легко преодолеть разрыв между традиционным CDI и более специализированными или динамическими требованиями к регистрации компонентов.

В постоянно развивающемся мире Java-фреймворков Quarkus продолжает выделяться, предлагая инновационные решения, такие как синтетические bean-компоненты, что делает его привлекательным выбором для современной, эффективной и гибкой разработки приложений. Оцените мощь синтетических bean-компонентов в Quarkus и поднимите внедрение зависимостей на новый уровень!

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/yanev/exploring-synthetic-beans-in-quarkus-a-powerful-extension-mechanism-fbd?1 Если есть какие-либо нарушения, пожалуйста, свяжитесь с [email protected] удалить его
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3