7.4. 管理 Bean
Jakarta EE では、Jakarta 管理 Bean 仕様 の共通定義が確立されています。Java EE については、プログラミングの制限が最小限であるコンテナー管理オブジェクトとして定義され、POJO (Plain Old Java Object) として知られるようになりました。管理対象 bean はリソースのインジェクション、ライフサイクルコールバック、インターセプターなどの基本サービスの小さなセットをサポートします。Jakarta Enterprise Beans や Jakarta Contexts and Dependency Injection などのコンパニオン仕様は、この基本モデルに基づいて構築されます。
ごくわずかな例外を除き、パラメーターのないコンストラクター (または @Inject
アノテーションが指定されたコンストラクター) を持つ具象 Java クラスは bean になります。これには、すべての JavaBean および Jakarta Enterprise Beans セッション Bean が含まれます。
7.4.1. Bean であるクラスのタイプ
管理対象 bean は Java クラスです。Jakarta EE については、管理対象 bean の基本的なライフサイクルやセマンティクスは、Jakarta 管理対象 Bean 1.0 の仕様で定義されています。bean クラス @ManagedBean
にアノテーションを付けることで明示的に管理対象 bean を宣言できますが、Contexts and Dependency Injection では不要です。この仕様によると、Contexts and Dependency Injection コンテナーでは、以下の条件を満たすクラスはすべて管理対象 bean として扱われます。
- 非静的な内部クラスではないこと。
-
具象クラス、あるいは
@Decorator
アノテーションが付与されている。 -
EJB コンポーネントを定義するアノテーションが付与されていないこと、あるいは
ejb-jar.xml
ファイルで Enterprise Java Bean クラスとして宣言されていること。 -
インターフェイス
javax.enterprise.inject.spi.Extension
を実装しないこと。 -
パラメーターのないコンストラクターか、
@Inject
アノテーションが付与されたコンストラクターがあること。 -
@Vetoed
アノテーションが付いていないこと、または@Vetoed
アノテーションが付けられたパッケージ内にないこと。
管理対象 bean の無制限の bean 型には、直接的あるいは間接的に実装する bean クラス、スーパークラスすべて、およびインターフェイスすべてが含まれます。
管理対象 Bean にパブリックフィールドがある場合は、デフォルトの @Dependent
スコープが必要です。
@Vetoed
@Vetoed
アノテーションは CDI 1.1 で導入されました。このアノテーションを追加することにより、Bean をインジェクションから除外できます。
@Vetoed public class SimpleGreeting implements Greeting { ... }
このコードでは、SimpleGreeting
Bean はインジェクションの対象となりません。
パッケージ内のすべての bean をインジェクションから除外できます。
@Vetoed package org.sample.beans; import javax.enterprise.inject.Vetoed;
org.sample.beans
パッケージ内の package-info.java
のこのコードにより、このパッケージ内のすべての Bean がインジェクションから除外されます。
ステートレス AX-RS リソースエンドポイントなどの Jakarta EE コンポーネントには、bean と見なされないように @Vetoed
を付けることができます。@Vetoed
アノテーションをすべての永続エンティティーに追加すると、BeanManager
がエンティティーを Jakarta コンテキストおよび依存関係インジェクション Bean として管理できなくなります。エンティティーに @Vetoed
アノテーションが付けられた場合は、インジェクションが行われません。これは、Java Persistence プロバイダーの破損原因となる操作を BeanManager
が実行しないようにするためです。
7.4.2. Contexts and Dependency Injection を使用したオブジェクトの Bean へのインジェクション
Contexts and Dependency Injection は、Contexts and Dependency Injection コンポーネントがアプリケーションで検出されると自動的にアクティベートされます。デフォルト値と異なるよう設定をカスタマイズする場合は、デプロイメントアーカイブに META-INF/beans.xml
ファイルまたは WEB-INF/beans.xml
ファイルを含めることができます。
他のオブジェクトにオブジェクトをインジェクトする
クラスのインスタンスを取得するには、bean 内でフィールドに
@Inject
アノテーションを付けます。public class TranslateController { @Inject TextTranslator textTranslator; ...
インジェクトしたオブジェクトのメソッドを直接使用します。
TextTranslator
にメソッドtranslate
があることを前提とします。// in TranslateController class public void translate() { translation = textTranslator.translate(inputText); }
Bean のコンストラクターでインジェクションを使用します。ファクトリーやサービスロケーターを使用して作成する代わりに、Bean のコンストラクターへオブジェクトをインジェクトできます。
public class TextTranslator { private SentenceParser sentenceParser; private Translator sentenceTranslator; @Inject TextTranslator(SentenceParser sentenceParser, Translator sentenceTranslator) { this.sentenceParser = sentenceParser; this.sentenceTranslator = sentenceTranslator; } // Methods of the TextTranslator class ... }
Instance(<T>)
インターフェイスを使用してインスタンスをプログラムにより取得します。Bean 型でパラメーター化されると、Instance
インターフェイスはTextTranslator
のインスタンスを返すことができます。@Inject Instance<TextTranslator> textTranslatorInstance; ... public void translate() { textTranslatorInstance.get().translate(inputText); }
オブジェクトを Bean にインジェクトすると、Bean は全オブジェクトのメソッドとプロパティーを使用できるようになります。Bean のコンストラクターにインジェクトするときに、インジェクションがすでに存在するインスタンスを参照する場合以外は、Bean のコンストラクターが呼び出されるとインジェクトされたオブジェクトのインスタンスが作成されます。たとえば、セッションの存続期間内にセッションスコープの Bean をインジェクトしても、新しいインスタンスは作成されません。