"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Explorando los frijoles sintéticos en Quarkus. Un poderoso mecanismo de extensión

Explorando los frijoles sintéticos en Quarkus. Un poderoso mecanismo de extensión

Publicado el 2024-09-02
Navegar:779

Exploring Synthetic Beans in Quarkus. A Powerful Extension Mechanism

En el mundo de Quarkus, el ámbito de la inyección de dependencia es rico y versátil, y ofrece a los desarrolladores una multitud de herramientas para administrar y controlar beans. Una de esas herramientas es el concepto de frijoles sintéticos. Los beans sintéticos son un poderoso mecanismo de extensión que le permite registrar beans cuyos atributos no se derivan de una clase, método o campo de Java. En cambio, todos los atributos de un frijol sintético están definidos por una extensión.

En este artículo, profundizaremos en el mundo de los frijoles sintéticos en Quarkus. Exploraremos la necesidad de frijoles sintéticos, sus aplicaciones prácticas y cómo crearlos y usarlos en sus aplicaciones Quarkus.

Entendiendo los frijoles sintéticos

En Quarkus, los beans son los componentes básicos de su aplicación, administrados por el marco de Contextos e Inyección de Dependencia (CDI). Normalmente, los beans CDI son clases de Java que están anotadas con varias anotaciones CDI, como @ApplicationScoped, @RequestScoped o @Inject. Estas anotaciones
permitir que CDI administre automáticamente el ciclo de vida y la inyección de beans.

Sin embargo, hay situaciones en las que es posible que necesites registrar un bean que no encaja perfectamente en el modelo CDI tradicional. Aquí es donde entran en juego los frijoles sintéticos. Los frijoles sintéticos son creados por extensiones y sus atributos están completamente definidos por estas extensiones. En el mundo del CDI normal, esto se lograría utilizando los métodos AfterBeanDiscovery.addBean() y SyntheticComponents.addBean(). En Quarkus, esto se logra usando SyntheticBeanBuildItem.

¿Cuándo necesitas frijoles sintéticos?

Entonces, ¿cuándo podrías necesitar usar frijoles sintéticos en Quarkus? Los frijoles sintéticos son una herramienta poderosa cuando:

  1. Integración de bibliotecas de terceros: Está trabajando con una biblioteca de terceros que no tiene anotaciones CDI pero debe integrarse en su aplicación basada en CDI. Los frijoles sintéticos te permiten cerrar esta brecha.

  2. Registro dinámico de beans: Debe registrar beans dinámicamente en tiempo de ejecución, según la configuración u otros factores. Los frijoles sintéticos le brindan la flexibilidad de crear y registrar frijoles sobre la marcha.

  3. Gestión de Bean personalizada: Necesita un control detallado sobre el alcance y el comportamiento de un Bean que no se puede lograr con anotaciones CDI estándar.

  4. Implementación de beans especializados: Desea crear beans especializados con atributos únicos que no se correspondan con las clases o métodos tradicionales de Java.

  5. Simulación de dependencias para pruebas: Los beans sintéticos proporcionan una forma útil de simular dependencias e inyectar implementaciones simuladas con fines de prueba.

SíntesisFinishedBuildItem

SynthesisFinishedBuildItem se utiliza para indicar que el proceso de registro y descubrimiento del bean CDI se ha completado. Esto permite que las extensiones sepan cuándo es seguro interactuar con los beans que se han registrado.

Por ejemplo:

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

Frijoles sintéticosRuntimeInitBuildItem

SyntheticBeansRuntimeInitBuildItem se utiliza para registrar una devolución de llamada que se invocará en tiempo de ejecución después de que se hayan inicializado todos los beans sintéticos. Esto es útil si necesita realizar una lógica de inicialización adicional que involucre beans sintéticos.

Por ejemplo:

@BuildStep
SyntheticBeansRuntimeInitBuildItem initSyntheticBeans(){

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

    }

La devolución de llamada pasada a SyntheticBeansRuntimeInitBuildItem recibirá un Set que contiene los ID de todos los beans sintéticos inicializados.

En resumen, SynthesisFinishedBuildItem indica que se realizó el descubrimiento de beans, mientras que SyntheticBeansRuntimeInitBuildItem permite inicializar la lógica dependiendo de los beans sintéticos.

Crear frijoles sintéticos con SyntheticBeanBuildItem

En Quarkus, crear beans sintéticos es un proceso sencillo, gracias a la clase SyntheticBeanBuildItem. Repasemos los pasos para crear y usar un frijol sintético:

  1. Crear la clase de frijol sintético: Comience definiendo la clase de frijol sintético. Esta clase será la base de su frijol sintético.
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. Crear una extensión Quarkus: Necesitará crear una extensión Quarkus para registrar su frijol sintético. Esta clase de extensión utilizará SyntheticBeanBuildItem para configurar su bean.

Enfoque de generación de código de bytes

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();
  }
}

El método .creator() en SyntheticBeanBuildItem se utiliza para generar el código de bytes que creará instancias del bean sintético en tiempo de ejecución.

El argumento pasado a .creator() es un Consumer que permite generar código de bytes de Java dentro de un método.

En este ejemplo:

  1. mc es la instancia de MethodCreator
  2. mc.returnValue(new MySyntheticBean()) genera el código de bytes para crear una nueva instancia de MySyntheticBean y devolverlo desde el método.

Básicamente, le estamos diciendo a Quarkus que genere un método que se parezca a:

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

Este método generado luego se llamará para crear una instancia de MySyntheticBean cuando sea necesario inyectarlo o usarlo.

La razón por la que se utiliza la generación de código de bytes es que los beans sintéticos no corresponden a clases/métodos reales de Java, por lo que tenemos que generar explícitamente un método para crear instancias de ellos

La salida de SyntheticBeanBuildItem es un código de bytes registrado en el momento de la compilación. Esto limita cómo se crean las instancias en tiempo de ejecución. Las opciones comunes son:

  1. Generar código de bytes directamente a través de .creator()
  2. Usar una subclase de BeanCreator
  3. Producir instancia mediante el método @Recorder

Enfoque del registrador

Los enfoques @Record y .runtimeValue() son formas alternativas de proporcionar instancias para beans sintéticos en Quarkus.

Esto le permite crear una instancia del bean sintético mediante un método de clase de grabadora anotado con @Record(STATIC_INIT).

Por ejemplo:

@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());
  }

Aquí .runtimeValue() hace referencia al método de grabación para crear una instancia del bean. Esto permite pasar un RuntimeValue directamente para proporcionar la instancia del bean sintético.

Por ejemplo:

@BuildStep 
SyntheticBeanBuildItem syntheticBean(){

    RuntimeValue bean= //...

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

    }

El RuntimeValue podría provenir de un registrador, proveedor, proxy, etc.

En resumen:

  • @Record es un enfoque para generar RuntimeValue
  • .runtimeValue() establece RuntimeValue en SyntheticBeanBuildItem

Ambos logran el mismo objetivo de proporcionar una instancia de tiempo de ejecución, solo que de maneras ligeramente diferentes.

Cuando se trata de proporcionar instancias de tiempo de ejecución para beans sintéticos en Quarkus, consideraría el uso de grabadoras (a través de @Record) como un enfoque más avanzado en comparación con la generación directa de código de bytes
con .creator() o proporcionando RuntimeValues ​​simples.

Aquí hay algunas razones por las que el uso de grabadoras puede ser más avanzado:

  • Más encapsulación - La lógica para crear instancias de beans está contenida en una clase de grabadora separada en lugar de directamente en los pasos de compilación. Esto mantiene los pasos de construcción ágiles.
  • Reutilizar: Los métodos de grabación se pueden reutilizar en varios beans sintéticos en lugar de reescribir la lógica del creador.
  • Datos en tiempo de ejecución: Los métodos de grabación se ejecutan en tiempo de ejecución para que puedan aprovechar los recursos, configuraciones, servicios, etc. del tiempo de ejecución para construir beans.
  • Inyección de dependencia: Los métodos de grabación pueden inyectar otros servicios.
  • Control del ciclo de vida: Los métodos de grabador anotados con @Record(STATIC_INIT) o @Record(RUNTIME_INIT) brindan más control sobre el ciclo de vida de creación de instancias del bean.
  • Beans administrados: Los beans instanciados dentro de las grabadoras pueden ser beans administrados por CDI.

Entonces, en resumen, los métodos de grabación brindan más encapsulación, flexibilidad y acceso a datos y servicios en tiempo de ejecución para crear instancias de beans sintéticos. Permiten una lógica de producción de beans más avanzada en comparación con la generación directa de códigos de bytes.

Sin embargo, la generación directa de código de bytes con .creator() aún puede ser útil para casos simples en los que las grabadoras pueden ser excesivas. Pero a medida que aumentan las necesidades de frijoles sintéticos, las flautas dulces son una herramienta más potente y
enfoque avanzado.

Es posible configurar un bean sintético en Quarkus para que se inicialice durante la fase RUNTIME_INIT en lugar de la fase STATIC_INIT predeterminada.

Aquí hay un ejemplo:

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

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

    }

Los puntos clave son:

  • Utilice setRuntimeInit() en SyntheticBeanBuildItem para marcarlo para RUNTIME_INIT
  • El método de grabación debe anotarse con @Record(RUNTIME_INIT)
  • No se puede acceder a los beans sintéticos de inicio del tiempo de ejecución durante STATIC_INIT

Entonces, en resumen, los beans sintéticos se pueden inicializar de manera perezosa durante RUNTIME_INIT para los casos en los que no se necesita una instanciación ansiosa de STATIC_INIT. Esto permite optimizar el tiempo de inicio.

Usa el frijol sintético: Ahora que tu frijol sintético está registrado, puedes inyectarlo y usarlo en tu aplicación.

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();
  }
}

Ejecutando su aplicación: Cree y ejecute su aplicación Quarkus como de costumbre, y el frijol sintético estará disponible para inyección y uso.

Conclusión

Los beans sintéticos en Quarkus proporcionan un mecanismo poderoso para integrar bibliotecas externas, registrar beans dinámicamente y personalizar el comportamiento de los beans en sus aplicaciones basadas en CDI. Estos beans, cuyos atributos se definen mediante extensiones en lugar de clases de Java, ofrecen flexibilidad y versatilidad en la gestión de dependencias.

Como hemos explorado en este artículo, crear y usar frijoles sintéticos en Quarkus es un proceso sencillo. Al aprovechar las extensiones SyntheticBeanBuildItem y Quarkus, puede cerrar la brecha entre el CDI tradicional y los requisitos de registro de beans más especializados o dinámicos.

En el panorama en constante evolución de los marcos de Java, Quarkus continúa destacándose al ofrecer soluciones innovadoras como beans sintéticos, lo que lo convierte en una opción convincente para el desarrollo de aplicaciones modernas, eficientes y flexibles. ¡Aprovecha el poder de los frijoles sintéticos en Quarkus y lleva tu inyección de dependencia al siguiente nivel!

Declaración de liberación Este artículo se reproduce en: https://dev.to/yanev/exploring-synthetic-beans-in-quarkus-a-powerful-extension-mechanism-fbd?1 Si hay alguna infracción, comuníquese con [email protected] para borrarlo
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3