7.4. 管理 Bean
Jakarta EE では、Jakarta 管理 Bean 仕様 の共通定義が確立されています。Jakarta 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アノテーションが付与されている。 -
Jakarta Enterprise Beans コンポーネント定義アノテーションでアノテーションが付けられていないか、
ejb-jar.xmlファイルで Jakarta Enterprise Beans Bean クラスとして宣言されていません。 -
インターフェイス
javax.enterprise.inject.spi.Extensionを実装しないこと。 -
パラメーターのないコンストラクターか、
@Injectアノテーションが付与されたコンストラクターがあること。 -
@Vetoedアノテーションが付いていないこと、または@Vetoedアノテーションが付けられたパッケージ内にないこと。
管理対象 bean の無制限の bean 型には、直接的あるいは間接的に実装する bean クラス、スーパークラスすべて、およびインターフェイスすべてが含まれます。
管理対象 Bean にパブリックフィールドがある場合は、デフォルトの @Dependent スコープが必要です。
@Vetoed
このクラスによって定義された 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 がインジェクションから除外されます。
ステートレス Jakarta Enterprise Beans や Jakarta RESTful Web Services リソースエンドポイントなどの Jakarta EE コンポーネントには、bean と見なされないように @Vetoed を付けることができます。@Vetoed アノテーションをすべての永続エンティティーに追加すると、BeanManager がエンティティーを Jakarta コンテキストおよび依存関係インジェクション Bean として管理できなくなります。エンティティーに @Vetoed アノテーションが付けられた場合は、インジェクションが行われません。これは、Jakarta 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 をインジェクトしても、新しいインスタンスは作成されません。