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.
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.
Entonces, ¿cuándo podrías necesitar usar frijoles sintéticos en Quarkus? Los frijoles sintéticos son una herramienta poderosa cuando:
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.
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.
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.
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.
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.
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 }
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
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.
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:
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!"); } }
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
En este ejemplo:
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:
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(){ RuntimeValuebean= //... return SyntheticBeanBuildItem .configure(MySyntheticBean.class) .runtimeValue(bean); }
El RuntimeValue podría provenir de un registrador, proveedor, proxy, etc.
En resumen:
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:
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:
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.
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!
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