Maison > Java > javaDidacticiel > Explorer les haricots synthétiques à Quarkus. Un mécanisme d'extension puissant

Explorer les haricots synthétiques à Quarkus. Un mécanisme d'extension puissant

PHPz
Libérer: 2024-08-30 06:02:32
original
395 Les gens l'ont consulté

Exploring Synthetic Beans in Quarkus. A Powerful Extension Mechanism

Dans le monde de Quarkus, le domaine de l'injection de dépendances est riche et polyvalent, offrant aux développeurs une multitude d'outils pour gérer et contrôler les beans. L’un de ces outils est le concept de haricots synthétiques. Les beans synthétiques sont un puissant mécanisme d'extension qui vous permet d'enregistrer des beans dont les attributs ne sont pas dérivés d'une classe, d'une méthode ou d'un champ Java. Au lieu de cela, tous les attributs d'un haricot synthétique sont définis par une extension.

Dans cet article, nous allons plonger en profondeur dans le monde des haricots synthétiques chez Quarkus. Nous explorerons le besoin de haricots synthétiques, leurs applications pratiques et comment les créer et les utiliser dans vos applications Quarkus.

Comprendre les haricots synthétiques

Dans Quarkus, les beans sont les éléments constitutifs de votre application, gérés par le framework Contexts and Dependency Injection (CDI). En règle générale, les beans CDI sont des classes Java annotées avec diverses annotations CDI telles que @ApplicationScoped, @RequestScoped ou @Inject. Ces annotations
permettre à CDI de gérer automatiquement le cycle de vie et l'injection des beans.

Cependant, il existe des situations dans lesquelles vous devrez peut-être enregistrer un bean qui ne rentre pas parfaitement dans le modèle CDI traditionnel. C’est là que les haricots synthétiques entrent en jeu. Les beans synthétiques sont créés par des extensions et ont leurs attributs entièrement définis par ces extensions. Dans le monde du CDI classique, vous y parviendrez en utilisant les méthodes AfterBeanDiscovery.addBean() et SyntheticComponents.addBean(). Dans Quarkus, cela est accompli en utilisant SyntheticBeanBuildItem.

Quand avez-vous besoin de haricots synthétiques ?

Alors, quand pourriez-vous avoir besoin d'utiliser des haricots synthétiques dans Quarkus ? Les haricots synthétiques sont un outil puissant lorsque :

  1. Intégration de bibliothèques tierces : Vous travaillez avec une bibliothèque tierce qui n'a pas d'annotations CDI mais doit être intégrée à votre application basée sur CDI. Les haricots synthétiques vous permettent de combler cet écart.

  2. Enregistrement dynamique des beans : Vous devez enregistrer les beans de manière dynamique au moment de l'exécution, en fonction de la configuration ou d'autres facteurs. Les haricots synthétiques vous offrent la flexibilité nécessaire pour créer et enregistrer des haricots à la volée.

  3. Gestion personnalisée des beans : Vous avez besoin d'un contrôle précis sur la portée et le comportement d'un bean qui ne peut pas être obtenu avec les annotations CDI standard.

  4. Implémentation de beans spécialisés : Vous souhaitez créer des beans spécialisés avec des attributs uniques qui ne correspondent pas aux classes ou méthodes Java traditionnelles.

  5. Dépendances moqueuses pour les tests : Les beans synthétiques fournissent un moyen utile de simuler les dépendances et d'injecter des implémentations simulées à des fins de test.

SynthesisFinishedBuildItem

Le SynthesisFinishedBuildItem est utilisé pour indiquer que le processus de découverte et d'enregistrement du bean CDI est terminé. Cela permet aux extensions de savoir quand il est sûr d'interagir avec les beans qui ont été enregistrés.

Par exemple :

@BuildStep  
void onSynthesisFinished(SynthesisFinishedBuildItem synthesisFinished){
    // CDI bean registration is complete, can now safely interact with beans
    }
Copier après la connexion

SyntheticBeansRuntimeInitBuildItem

Le SyntheticBeansRuntimeInitBuildItem est utilisé pour enregistrer un rappel qui sera invoqué au moment de l'exécution une fois que tous les beans synthétiques ont été initialisés. Ceci est utile si vous devez effectuer une logique d'initialisation supplémentaire impliquant des beans synthétiques.

Par exemple :

@BuildStep
SyntheticBeansRuntimeInitBuildItem initSyntheticBeans(){

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

    }
Copier après la connexion

Le rappel transmis à SyntheticBeansRuntimeInitBuildItem recevra un Set contenant les identifiants de tous les haricots synthétiques initialisés.

Donc, en résumé, SynthesisFinishedBuildItem indique que la découverte du bean est terminée, tandis que SyntheticBeansRuntimeInitBuildItem permet d'initialiser la logique en fonction des beans synthétiques.

Création de haricots synthétiques avec SyntheticBeanBuildItem

Dans Quarkus, la création de beans synthétiques est un processus simple, grâce à la classe SyntheticBeanBuildItem. Passons en revue les étapes pour créer et utiliser un haricot synthétique :

  1. Créez la classe de haricots synthétiques : Commencez par définir la classe de haricots synthétiques. Ce cours sera la base de votre haricot synthétique.
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!");
  }
}
Copier après la connexion
  1. Créez une extension Quarkus : Vous devrez créer une extension Quarkus pour enregistrer votre bean synthétique. Cette classe d'extension utilisera SyntheticBeanBuildItem pour configurer votre bean.

Approche de génération de bytecode

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();
  }
}
Copier après la connexion

La méthode .creator() sur SyntheticBeanBuildItem est utilisée pour générer le bytecode qui créera des instances du bean synthétique au moment de l'exécution.

L'argument passé à .creator() est un Consumer qui permet de générer du bytecode Java à l'intérieur d'une méthode.

Dans cet exemple :

  1. mc is the MethodCreator instance
  2. mc.returnValue(new MySyntheticBean()) generates the bytecode to create a new instance of MySyntheticBean and return it from the method.

So essentially, we are telling Quarkus to generate a method that looks something like:

MySyntheticBean createSyntheticBean(){
    return new MySyntheticBean();
    }
Copier après la connexion

This generated method will then be called to instantiate the MySyntheticBean when it needs to be injected or used.

The reason bytecode generation is used is that synthetic beans do not correspond to real Java classes/methods, so we have to explicitly generate a method to instantiate them

The output of SyntheticBeanBuildItem is bytecode recorded at build time. This limits how instances are created at runtime. Common options are:

  1. Generate bytecode directly via .creator()
  2. Use a BeanCreator subclass
  3. Produce instance via @Recorder method

Recorder Approach

The @Record and .runtimeValue() approaches are alternate ways of providing instances for synthetic beans in Quarkus.

This allows you to instantiate the synthetic bean via a recorder class method annotated with @Record(STATIC_INIT).

For example:

@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());
  }
Copier après la connexion

Here the .runtimeValue() references the recorder method to instantiate the bean. This allows passing a RuntimeValue directly to provide the synthetic bean instance.

For example:

@BuildStep 
SyntheticBeanBuildItem syntheticBean(){

    RuntimeValue<MySyntheticBean> bean= //...

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

    }
Copier après la connexion

The RuntimeValue could come from a recorder, supplier, proxy etc.

So in summary:

  • @Record is one approach to generate the RuntimeValue
  • .runtimeValue() sets the RuntimeValue on the SyntheticBeanBuildItem

They both achieve the same goal of providing a runtime instance, just in slightly different ways.

When it comes to providing runtime instances for synthetic beans in Quarkus, I would consider using recorders (via @Record) to be a more advanced approach compared to directly generating bytecode
with .creator() or supplying simple RuntimeValues.

Here are some reasons why using recorders can be more advanced:

  • More encapsulation - The logic to instantiate beans is contained in a separate recorder class rather than directly in build steps. This keeps build steps lean.
  • Reuse - Recorder methods can be reused across multiple synthetic beans rather than rewriting creator logic.
  • Runtime data - Recorder methods execute at runtime so they can leverage runtime resources, configs, services etc. to construct beans.
  • Dependency injection - Recorder methods can inject other services.
  • Life cycle control - Recorder methods annotated with @Record(STATIC_INIT) or @Record(RUNTIME_INIT) give more control over bean instantiation life cycle.
  • Managed beans - Beans instantiated inside recorders can themselves be CDI managed beans.

So in summary, recorder methods provide more encapsulation, flexibility and access to runtime data and services for instantiating synthetic beans. They allow for more advanced bean production logic compared to direct bytecode generation.

However, direct bytecode generation with .creator() can still be useful for simple cases where recorders may be overkill. But as synthetic bean needs grow, recorders are a more powerful and
advanced approach.

It is possible to configure a synthetic bean in Quarkus to be initialized during the RUNTIME_INIT phase instead of the default STATIC_INIT phase.

Here is an example:

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

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

    }
Copier après la connexion

The key points are:

  • Use setRuntimeInit() on the SyntheticBeanBuildItem to mark it for RUNTIME_INIT
  • The recorder method must be annotated with @Record(RUNTIME_INIT)
  • The runtime init synthetic beans cannot be accessed during STATIC_INIT

So in summary, synthetic beans can be initialized lazily during RUNTIME_INIT for cases where eager STATIC_INIT instantiation is not needed. This allows optimizing startup time.

Use the Synthetic Bean: Now that your synthetic bean is registered, you can inject and use it in your application.

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();
  }
}
Copier après la connexion

Running Your Application: Build and run your Quarkus application as usual, and the synthetic bean will be available for injection and use.

Conclusion

Synthetic beans in Quarkus provide a powerful mechanism for integrating external libraries, dynamically registering beans, and customizing bean behavior in your CDI-based applications. These beans, whose attributes are defined by extensions rather than Java classes, offer flexibility and versatility in managing dependencies.

Comme nous l'avons exploré dans cet article, la création et l'utilisation de haricots synthétiques dans Quarkus sont un processus simple. En tirant parti des extensions SyntheticBeanBuildItem et Quarkus, vous pouvez combler de manière transparente le fossé entre le CDI traditionnel et les exigences d'enregistrement de beans plus spécialisées ou dynamiques.

Dans le paysage en constante évolution des frameworks Java, Quarkus continue de se démarquer en proposant des solutions innovantes telles que les beans synthétiques, ce qui en fait un choix incontournable pour le développement d'applications modernes, efficaces et flexibles. Adoptez la puissance des haricots synthétiques dans Quarkus et faites passer votre injection de dépendance au niveau supérieur !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal