Quarkus の世界では、依存関係注入の領域は豊富で多用途であり、開発者に Bean を管理および制御するための多数のツールを提供します。そのようなツールの 1 つは、合成 Bean の概念です。合成 Bean は、Java クラス、メソッド、またはフィールドから派生したものではない属性を持つ Bean を登録できる強力な拡張メカニズムです。代わりに、合成 Bean のすべての属性は拡張子によって定義されます。
この記事では、Quarkus の合成 Bean の世界を深く掘り下げていきます。合成 Bean の必要性、その実用的なアプリケーション、Quarkus アプリケーションで合成 Bean を作成して使用する方法について探っていきます。
Quarkus では、Bean はアプリケーションの構成要素であり、Contexts and dependency Injection (CDI) フレームワークによって管理されます。通常、CDI Bean は、@ApplicationScoped、@RequestScoped、または @Inject などのさまざまな CDI アノテーションが付けられた Java クラスです。これらの注釈
CDI が Bean のライフサイクルと注入を自動的に管理できるようにします。
ただし、状況によっては、従来の CDI モデルにうまく適合しない Bean を登録する必要がある場合があります。ここで合成豆が活躍します。合成 Bean は拡張機能によって作成され、その属性はこれらの拡張機能によって完全に定義されます。通常の CDI の世界では、AfterBeanDiscovery.addBean() メソッドと SyntheticComponents.addBean() メソッドを使用してこれを実現します。 Quarkus では、これは SyntheticBeanBuildItem.
を使用して実現されます。では、Quarkus で合成 Bean を使用する必要があるのはどのような場合でしょうか?合成 Bean は、次の場合に強力なツールとなります。
サードパーティ ライブラリの統合: CDI アノテーションを持たないサードパーティ ライブラリを使用していますが、CDI ベースのアプリケーションに統合する必要があります。合成 Bean を使用すると、このギャップを埋めることができます。
動的 Bean 登録: 構成やその他の要因に応じて、実行時に Bean を動的に登録する必要があります。合成 Bean を使用すると、その場で Bean を作成して登録できる柔軟性が得られます。
カスタマイズされた Bean 管理: 標準の CDI アノテーションでは実現できない、Bean のスコープと動作に対するきめ細かい制御が必要です。
特殊な Bean の実装: 従来の Java クラスやメソッドに対応しない固有の属性を持つ特殊な Bean を作成したいと考えています。
テスト用の依存関係のモック化: 合成 Bean は、テスト目的で依存関係をモックアウトし、モック実装を挿入する便利な方法を提供します。
SynthesisFinishedBuildItem は、CDI Bean の検出および登録プロセスが完了したことを示すために使用されます。これにより、拡張機能は、登録されている Bean と対話しても安全な時期を知ることができます。
例えば:
@BuildStep void onSynthesisFinished(SynthesisFinishedBuildItem synthesisFinished){ // CDI bean registration is complete, can now safely interact with beans }
SyntheticBeansRuntimeInitBuildItem は、すべての合成 Bean が初期化された後、実行時に呼び出されるコールバックを登録するために使用されます。これは、合成 Bean に関連する追加の初期化ロジックを実行する必要がある場合に役立ちます。
例えば:
@BuildStep SyntheticBeansRuntimeInitBuildItem initSyntheticBeans(){ return new SyntheticBeansRuntimeInitBuildItem(ids->{ // Perform logic with initialized synthetic beans }); }
SyntheticBeansRuntimeInitBuildItem に渡されるコールバックは、初期化されたすべての合成 Bean の ID を含む Set
要約すると、SynthesisFinishedBuildItem は Bean の検出が完了したことを示し、SyntheticBeansRuntimeInitBuildItem は合成 Bean に応じてロジックを初期化できます。
Quarkus では、SyntheticBeanBuildItem クラスのおかげで、合成 Bean の作成は簡単なプロセスです。合成 Bean を作成して使用する手順を見てみましょう:
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(); } }
SyntheticBeanBuildItem の .creator() メソッドは、実行時に合成 Bean のインスタンスを作成するバイトコードを生成するために使用されます。
.creator() に渡される引数は Consumer
この例では:
つまり、本質的には、次のようなメソッドを生成するように Quarkus に指示していることになります。
MySyntheticBean createSyntheticBean(){ return new MySyntheticBean(); }
この生成されたメソッドは、注入または使用する必要があるときに MySyntheticBean をインスタンス化するために呼び出されます。
バイトコード生成が使用される理由は、合成 Bean が実際の Java クラス/メソッドに対応していないため、それらをインスタンス化するメソッドを明示的に生成する必要があるためです
SyntheticBeanBuildItem の出力は、ビルド時に記録されたバイトコードです。これにより、実行時のインスタンスの作成方法が制限されます。一般的なオプションは次のとおりです:
@Record および .runtimeValue() アプローチは、Quarkus で合成 Bean のインスタンスを提供する代替方法です。
これにより、@Record(STATIC_INIT) アノテーションが付けられたレコーダー クラス メソッドを介して合成 Bean をインスタンス化できるようになります。
例えば:
@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() は、Bean をインスタンス化するためにレコーダー メソッドを参照します。これにより、RuntimeValue を直接渡して合成 Bean インスタンスを提供できるようになります。
例えば:
@BuildStep SyntheticBeanBuildItem syntheticBean(){ RuntimeValuebean= //... return SyntheticBeanBuildItem .configure(MySyntheticBean.class) .runtimeValue(bean); }
RuntimeValue は、レコーダー、サプライヤー、プロキシなどから取得される可能性があります。
要約すると:
どちらもランタイム インスタンスを提供するという同じ目標を達成しますが、方法は少し異なります。
Quarkus で合成 Bean のランタイム インスタンスを提供する場合、バイトコードを直接生成するよりもより高度なアプローチとして、(@Record 経由で) レコーダーを使用することを検討します。
.creator() を使用するか、単純な RuntimeValues.
レコーダーの使用がより高度になる理由をいくつか示します:
要約すると、レコーダー メソッドは、合成 Bean をインスタンス化するためのより多くのカプセル化、柔軟性、および実行時データとサービスへのアクセスを提供します。これらにより、直接バイトコード生成と比較して、より高度な Bean 生成ロジックが可能になります。
ただし、.creator() による直接バイトコード生成は、レコーダーが過剰になる可能性がある単純な場合には依然として役立ちます。しかし、合成豆のニーズが高まるにつれ、レコーダーはより強力になり、
高度なアプローチ。
デフォルトの STATIC_INIT フェーズではなく、RUNTIME_INIT フェーズ中に初期化されるように Quarkus の合成 Bean を設定することが可能です。
これが例です:
@BuildStep @Record(RUNTIME_INIT) SyntheticBeanBuildItem lazyBean(BeanRecorder recorder){ return SyntheticBeanBuildItem .configure(MyLazyBean.class) .setRuntimeInit() // initialize during RUNTIME_INIT .runtimeValue(recorder.createLazyBean()); }
重要なポイントは次のとおりです:
要約すると、積極的な STATIC_INIT インスタンス化が必要ない場合、合成 Bean は RUNTIME_INIT 中に遅延的に初期化できます。これにより、起動時間を最適化できます。
合成 Bean を使用する: 合成 Bean が登録されたので、それをアプリケーションに注入して使用できます。
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 の動作のカスタマイズのための強力なメカニズムを提供します。これらの Bean は、属性が Java クラスではなく拡張機能によって定義されており、依存関係の管理に柔軟性と多用途性をもたらします。
この記事で説明したように、Quarkus での合成 Bean の作成と使用は簡単なプロセスです。 SyntheticBeanBuildItem と Quarkus 拡張機能を活用することで、従来の CDI と、より専門的または動的な Bean 登録要件との間のギャップをシームレスに埋めることができます。
進化し続ける Java フレームワークの状況において、Quarkus は合成 Bean などの革新的なソリューションを提供することで傑出し続けており、現代的で効率的かつ柔軟なアプリケーション開発にとって魅力的な選択肢となっています。 Quarkus の合成 Bean のパワーを活用して、依存関係の注入を次のレベルに引き上げましょう!
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3