9 Contexts and Dependency Injection for the Java EE Platformの使用方法

WebLogic Server は、Contexts and Dependency Injection (CDI)仕様の実装を提供します。CDI仕様には、注入を使用してアプリケーション内の依存関係を指定するための一連のサービスが定義されています。CDIは、Beanのコンテキストに基づいたライフ・サイクル管理、型保証注入ポイント、疎結合イベント・フレームワーク、疎結合インターセプタおよびデコレータ、Beanのかわりの実装、Unified Expression Language (EL)によるBeanのナビゲーション、CDI拡張がサード・パーティのフレームワークまたは将来のJava EEコンポーネントをサポートできるようにするサービス・プロバイダ・インタフェース(SPI)を提供します。

この章の内容は次のとおりです。

CDI for the Java EE Platformについて

Java EEプラットフォーム仕様のCDIは、以前はWeb Beanと呼ばれていました。CDI注入により、WebアプリケーションでJSFテクノロジとともにマネージドBeanを簡単に使用できるようになります。

CDIは、Java Specification Request (JSR) 365: Contexts and Dependency Injection for the Java 2.0によって指定されています。CDIは、次の関連する仕様を使用します。

CDIは、次の機能を提供します。

  • コンテキスト。この機能により、ステートフル・コンポーネントのライフ・サイクルおよび相互作用を、明確に定義されているが拡張可能なライフ・サイクル・コンテキストにバインドできるようになります。

  • 依存関係インジェクション。この機能により、型保証された方法でコンポーネントをアプリケーションに注入でき、デプロイメント時に特定のインタフェースのどの実装を注入するのかを選択できます。

CDIは、次のようなJava EEの主なコンポーネント・テクノロジと統合されます。

  • サーブレット

  • JavaServer Pages (JSP)

  • JavaServer Faces (JSF)

  • Enterprise JavaBeans (EJB)

  • Java EE Connector Architecture (JCA)

  • Webサービス

このような統合により、サーブレットやEJBコンポーネントなど標準Java EEオブジェクトが、依存関係のCDI注入を使用できるようになります。CDI注入により、たとえば、WebアプリケーションでJSFテクノロジとともにマネージドBeanを簡単に使用できるようになります。

Java EE 8チュートリアルJava EEプラットフォームのコンテキストおよび依存関係インジェクションの概要に関する項を参照してください。

CDI 2.0の例

次のようなJava EE 8のサンプル(CDI 2.0の新機能のデモ)が用意されています。
  • 非同期イベント – 非同期イベントの生成方法と、シングルトンEJBによるこれらのイベントの消費方法を示します。

  • オブザーバ順序付け – シングルトンEJBが優先度に従ってイベントを消費する方法を示します。

  • インターセプト・ファクトリ – InterceptionFactoryにより、指定されたアノテーションを動的に追加してクラス・インスタンスを生成する方法を示します。

詳細は、WebLogic Server配布キットのCDI 2.0の例Oracle_HOME\wlserver\samples\server\examples\src\examples\javaee8\cdiを参照してください。この場合、ORACLE_HOMEは、WebLogic Serverをインストールしたディレクトリを表します。『Oracle WebLogic Serverの理解』「サンプル・アプリケーションおよびサンプル・コード」を参照してください

CDI 1.1の例

CDIの使用方法を示すJava EE 7の例は、Oracle_HOME\wlserver\samples\server\examples\src\examples\javaee7\cdiにインストールされたcdiサンプル・アプリケーションで提供されています。この場合、ORACLE_HOMEは、WebLogic Serverをインストールしたディレクトリを表します。『Oracle WebLogic Serverの理解』「サンプル・アプリケーションおよびサンプル・コード」を参照してください

マネージドBeanの定義

マネージドBeanは、CDIアプリケーションの基本コンポーネントであり、CDIによって作成および管理できるBeanを定義します。

Beanは、CDIによって作成および管理できるオブジェクトのソースです。Java EE 8チュートリアルBeanに関する項を参照してください。

マネージドBeanを定義するには、次の条件のいずれかを満たす最上位レベルのプレーンな従来型Javaオブジェクト(POJO)クラスを定義します。

  • このクラスは、他のJava EE仕様によってマネージドBeanとなるように定義されています。

  • このクラスは、Java EE 8チュートリアルCDIマネージドBeanに関する項にリストされているJSR 346で必要とされる条件をすべて満たします。

ノート:

マネージドBeanを定義するために、アノテーションなど特別な宣言は必要ありません。アプリケーションのマネージドBeanを注入に使用できるようにするには、「CDIアプリケーションの構成」の説明に従ってアプリケーションを構成する必要があります

Beanの注入

自身で定義するBeanを使用するには、それらを、JavaServer Facesなどのアプリケーションが使用できる別のBeanに注入します。

Java EE 8チュートリアルBeanの注入に関する項を参照してください。

CDIでは、Bean名ではなく、注入ポイントで指定されているJavaの型に基づいてBeanクラスを選択することで、型を保証してBeanを注入できます。CDIでは、注入ポイントのJavaの型からBeanを注入する場所も判別されます。

この点において、CDI BeanインジェクションはJava EE 5仕様で導入されたリソース・インジェクションとは異なり、リソースの文字列名から呼び出すためにリソースを選択します。たとえば、javax.annotation.Resourceアノテーションで注入されるデータ・ソースは、その文字列名によって識別されます。

Beanを注入するには、注入するBeanを使用するクラス内に注入ポイントを作成することで、Beanのインスタンスを取得します。javax.inject.Injectアノテーションで、次のプログラム要素の1つに注釈付けすることで注入ポイントを作成します。

  • インスタンス・クラス・フィールド

  • イニシャライザ・メソッド・パラメータ

  • Beanコンストラクタ・パラメータ

例9-1は、@Injectアノテーションを使用してBeanを別のBeanに注入する方法を示します。

例9-1 別のBeanへのBeanの注入

この例では、インスタンス・クラス・フィールドに注釈付けして、BeanクラスGreetingのインスタンスをクラスPrinterに注入します。

import javax.inject.Inject;
...
public class Printer {
    @Inject Greeting greeting;
    ...
}

Beanのスコープの定義

Beanのスコープは、そのBeanを使用するアプリケーションとユーザーの対話の期間を定義します。Webアプリケーションが、別のBeanクラスを注入するBeanを使用できるようにするには、そのBeanがアプリケーションとユーザーの対話の期間にわたって状態を保持できるようにする必要があります。

Beanのスコープを定義するには、Beanのクラス宣言にそのスコープのアノテーションを付けます。javax.enterprise.contextパッケージは、次のスコープを宣言します。

  • @RequestScoped

  • @SessionScoped

  • @ApplicationScoped

  • @ConversationScoped

  • @Dependent

これらのスコープの詳細は、Java EE 8チュートリアルスコープの使用方法に関する項を参照してください。

Beanのスコープを定義しない場合、Beanのスコープはデフォルトの@Dependentになります。@Dependentのスコープは、そのBeanのライフ・サイクルを、そのBeanの注入先のオブジェクトのライフ・サイクルにすることを指定します。

@Dependent以外の事前定義済スコープは、コンテキスト・スコープです。CDIは、コンテキスト・スコープのBeanを、Java EE仕様によって定義されるライフ・サイクルを持つコンテキストに配置します。たとえば、セッション・コンテキストとそのBeanは、HTTPセッションのライフタイムの間のみ存在します。注入されるBeanへの参照は、コンテキストを認識しています。参照は常に、参照するスレッドのコンテキストに関連付けられたBeanに適用されます。CDIコンテナによって、オブジェクトは、それらのオブジェクトに対して指定されているスコープによって決定される適切な時点で作成され、注入されます。

例9-2は、Beanのスコープを定義する方法を示します。

例9-2 Beanのスコープの定義

この例では、Accountant Beanクラスのスコープを@RequestScopedと定義します。

この例のAccountantクラスは、@BeanCounter修飾子によって修飾されています。詳細は、「修飾子の使用方法」を参照してください

package com.example.managers;

import javax.enterprise.context.RequestScoped;

@RequestScoped
@BeanCounter
public class Accountant implements Manager
{
 ...
}

注入ポイントでのBeanのスコープのオーバーライド

注入ポイントでのBeanのスコープのオーバーライドにより、アプリケーションは、デフォルト・スコープ@Dependentを持つBeanの新しいインスタンスをリクエストできます。@Dependentのスコープは、そのBeanのライフ・サイクルを、そのBeanの注入先のオブジェクトのライフ・サイクルにすることを指定します。

CDIコンテナは、インスタンスにその他のライフ・サイクル管理を提供しません。スコープの詳細は、「Beanのスコープの定義」を参照してください

ノート:

Beanのスコープのオーバーライドによる影響は、特にオーバーライドされるスコープが@Request@Sessionの場合に、予期できない望ましくないものになることがあります。

注入ポイントでBeanのスコープをオーバーライドするには、@Injectアノテーションのかわりにjavax.enterprise.inject.Newアノテーションを使用することでBeanを注入します。@Injectアノテーションの詳細は、「Beanの注入」を参照してください

修飾子の使用方法

修飾子によって、特定のBeanタイプの実装を複数提供できます。

修飾子を使用する場合、開発時に複数の実装の中から選択します。Java EE 8チュートリアル修飾子の使用に関する項を参照してください。

ノート:

デプロイメント時に複数の代替の実装の中から選択するには、「Beanタイプの代替の実装の提供」の説明に従って代替を使用します

修飾子の使用方法には、次の項で説明するタスクが含まれます。

Beanタイプの実装に対する修飾子の定義

修飾子は、アプリケーションによって定義されるアノテーションであり、Beanタイプの実装の識別を可能にします。提供するBeanタイプの実装ごとに修飾子を1つ定義します。

修飾子は、Beanタイプの複数の実装を提供し、かつ代替を使用していない場合にのみ定義します。Beanタイプに対して修飾子が定義されていない場合、そのタイプのBeanが注入されるときにCDIによって事前定義済修飾子@Defaultが適用されます。

ノート:

CDIでは、修飾子が特定のBeanに一意である必要はありません。1つの修飾子を複数のBeanタイプに定義できます。

修飾子を定義するには:

  1. その修飾子を表すJavaアノテーション・タイプを定義します。
  2. javax.inject.Qualifierアノテーションでアノテーション・タイプの宣言に注釈付けします。
  3. 実行時に仮想マシンによってその修飾子が保持されることを指定します。

    このためには、java.lang.annotation.Retention(RUNTIME)メタアノテーションを使用します。

  4. その修飾子をプログラム要素METHODFIELDPARAMETERおよびTYPEに適用できることを指定します。

    このためには、java.lang.annotation.Target({METHOD, FIELD, PARAMETER, TYPE})メタアノテーションを使用します。

次の例では、修飾子@BeanCounterおよび@PeopleManagerを、同じBeanタイプの別々の実装に対して定義する方法を示します。

例9-3 @BeanCounter修飾子の定義

この例では、@BeanCounter修飾子を定義します。

package com.example.managers;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface BeanCounter {}

例9-4 @PeopleManager修飾子の定義

この例では、@PeopleManager修飾子を定義します。

package com.example.managers;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface PeopleManager {}

Beanへの修飾子の適用

Beanに修飾子を適用すると、Beanタイプの実装が特定されます。1つのBeanに、任意の数の修飾子を適用することも、修飾子を適用しないこともできます。Beanに修飾子が適用されていない場合、CDIによって暗黙的に事前定義済修飾子@DefaultがそのBeanに適用されます。

ノート:

CDIでは、修飾子が特定のBeanに一意である必要はありません。1つのアプリケーション内で使用可能な一連のBeanで異なるタイプのBeanに同じ修飾子を適用できます。

修飾子をBeanに適用するには、そのBeanのクラス宣言に、適用する各修飾子で注釈付けします。Beanに適用する修飾子は、「Beanタイプの実装に対する修飾子の定義」の説明に従って定義する必要があります

次の例では、修飾子@BeanCounterおよび@PeopleManagerManager Beanタイプの別々の実装に対して適用する方法を示します。

例9-5 Beanへの@BeanCounter修飾子の適用

この例では、@BeanCounter修飾子をAccountantクラスに適用します。Accountantクラスは、Manager Beanタイプの実装です。@BeanCounter修飾子は、例9-3で定義されています。

package com.example.managers;
...
@BeanCounter
public class Accountant implements Manager
{...}

例9-6 Beanへの@PeopleManager修飾子の適用

この例では、@PeopleManager修飾子をBossクラスに適用します。Bossクラスは、Manager Beanタイプの実装です。@PeopleManager修飾子は、例9-4で定義されています。

package com.example.managers;
...
@PeopleManager
public class Boss implements Manager
{...}

修飾Beanの注入

修飾Beanを注入するには、注入ポイントを作成し、その注入ポイントにBeanの修飾子で注釈付けします。注入ポイントの修飾子は、注入ターゲットの全体的な要件を定義します。CDIアプリケーションには、注入ポイントのタイプと、注入ポイントに注釈付けされている修飾子に一致するCDIマネージドBeanが含まれている必要があります。それ以外の場合は、デプロイメント・エラーが発生します。注入ポイントの作成方法の詳細は、「Beanの注入」を参照してください

注入ポイントに注釈付けしない場合、デフォルトで事前定義済修飾子@Defaultがその注入ポイントに適用されます。

CDIでは、注入ポイントは、最初にBeanタイプを一致させ、次にそのタイプの実装を注入ポイントの修飾子と一致させることで解決されます。

アクティブなBeanクラスのうちの1つのみを、注入ポイントのBeanタイプおよび修飾子と一致させることができます。それ以外の場合は、エラーが発生します。

Beanクラスは、次の状況のいずれかでアクティブです。

  • Beanクラスが、有効化されている代替です。

  • Beanクラスが、代替でなく、そのBeanタイプに対して有効化されている代替がありません。

代替の詳細は、「Beanタイプの代替の実装の提供」を参照してください

例9-7は、修飾Beanの注入方法を示します。

例9-7 修飾Beanの注入

この例では、Manager Beanタイプの@BeanCounter実装を注入します。Manager Beanタイプは、次のクラスによって実装されています。

  • Accountant例9-5に示しています。

  • Boss例9-6に示しています。

この例では、Accountantクラスが注入されます。それは、このクラスのBeanタイプと修飾子が、注入ポイントのBeanタイプと修飾子に一致するためです。

package com.example.managers;
...
import javax.inject.Inject;
...
public class PennyPincher { 
   @Inject @BeanCounter Manager accountant;
   ...
}

Beanタイプの代替の実装の提供

エンタープライズ・アプリケーションの開発、テスト、および本番デプロイメントの各環境は、大きく異なる場合があります。構成、リソースの可用性、およびパフォーマンスの要件の相違により、1つの環境に適したBeanクラスが、別の環境には合わないことがあります。Beanタイプの代替の実装を提供することにより、そのような異なる要件を満たすためにデプロイメント時にアプリケーションを変更できます。

同じアプリケーションでも、デプロイメント・シナリオの相違によって、異なるビジネス・ロジックが必要とされる場合もあります。たとえば、注文処理アプリケーションでは、国固有の消費税法によって国固有の消費税のビジネス・ロジックが必要な場合もあります。

CDIでは、対応するプライマリの実装のかわりに、任意の数の代替のBeanタイプの実装から注入するものを選択できます。Java EE 8チュートリアルCDIアプリケーションでの代替の使用に関する項を参照してください。

ノート:

開発時に複数の代替の実装から選択するには、「修飾子の使用方法」の説明に従って修飾子を使用します

Beanタイプの代替の実装の提供には、次の項で説明するタスクが含まれます。

Beanタイプの代替の実装の定義

Beanタイプの代替の実装を定義するには:

  1. Beanタイプのプライマリの実装と同じBeanタイプのBeanクラスを作成します。

    どの代替もアプリケーションに注入できるようにするには、すべての代替とプライマリの実装が、すべて同じBeanタイプであることが必要です。Beanの注入方法の詳細は、「Beanの注入」を参照してください

  2. avax.enterprise.inject.Alternativeアノテーションで実装のクラス宣言に注釈付けします。

    ノート:

    デフォルトで必ずプライマリの実装が選択されるようにするには、プライマリの実装のクラス宣言に@Alternativeで注釈付けしないでください。

次の例では、1つのBeanタイプのプライマリの実装と代替の実装の宣言を示します。代替の実装は、テストで使用するための模擬の実装です。

例9-8 Beanタイプのプライマリの実装の宣言

この例では、BeanタイプOrderのプライマリの実装OrderImplを宣言します。

package com.example.orderprocessor;
...
public class OrderImpl implements Order {
 ...
}

例9-9 Beanタイプの代替の実装の宣言

この例では、BeanタイプOrderの代替の実装MockOrderImplを宣言します。このBeanタイプのプライマリの実装の宣言を例9-8に示します。

package com.example.orderprocessor;
...
import javax.enterprise.inject.Alternative;

@Alternative
public class MockOrderImpl implements Order {
 ...
}

アプリケーションに対するBeanタイプの代替の実装の選択

デフォルトでは、CDIはアプリケーションへの注入にBeanタイプのプライマリの実装を選択します。代替の実装を注入する必要がある場合は、明示的にその代替を選択する必要があります。

アプリケーションに対して代替の実装を選択するには:

  1. beans.xmlファイルのalternatives要素に、代替のclass要素を追加します。
  2. class要素に、代替の完全修飾クラス名を指定します。

beans.xmlファイルの詳細は、「CDIアプリケーションの構成」を参照してください

例9-16は、Beanタイプの代替の実装を選択するためのbeans.xmlファイルのclass要素を示しています。

例9-10 Beanタイプの代替の実装の選択

この例では、代替の実装com.example.orderprocessor.MockOrderImplを選択します。

...
<alternatives>
    <class>com.example.orderprocessor.MockOrderImpl</class>
</alternatives>
...

セッションBeanへのスコープと修飾子の適用

CDIでは、スコープおよび修飾子をセッションBeanに適用できます。

セッションBeanは、次の要件のいずれかを満たすEJBコンポーネントです。

  • Beanを実装するクラスには、次のいずれかのアノテーションが付いています。

  • そのBeanが、ejb-jar.xmlデプロイメント記述子ファイルにリストされています。

セッションBeanの詳細は、次のドキュメントを参照してください。

セッションBeanへのスコープの適用

CDIによりセッションBeanに適用できるスコープは、表9-1に示すようにセッションBeanのタイプに応じて異なります。

表9-1 セッションBeanに適用できるCDIスコープ

セッションBeanタイプ 適用できるスコープ

シングルトン

次のスコープのいずれかです。

  • Dependent

  • Application

ステートフル

任意

ステートレス

Dependent

CDIにおけるスコープの詳細は、「Beanのスコープの定義」を参照してください

CDIで、ステートフル・セッションBeanへの参照が注入されるときは、CDIによってBeanが作成され、Beanのフィールドが注入され、そのスコープに応じてステートフル・セッションBeanが管理されます。コンテキストを破棄するときは、CDIによってステートフル・セッションBeanの削除メソッドがコールされ、そのBeanが削除されます。

セッションBeanへの修飾子の適用

CDIでは、任意の修飾子をセッションBeanに適用できます。CDIでは、セッションBeanに適用できる修飾子のタイプに制限はありません。CDIにおける修飾子の詳細は、「修飾子の使用方法」を参照してください

プロデューサ・メソッド、ディスポーザ・メソッド、およびプロデューサ・フィールドの使用方法

プロデューサ・メソッドは、注入可能なオブジェクトを生成するメソッドです。ディスポーザ・メソッドは、アプリケーションが、プロデューサ・メソッドから返されたオブジェクトに、カスタマイズされたクリーンアップを実行できるようにします。プロデューサ・フィールドは、オブジェクトを生成するBeanのフィールドです。

プロデューサ・フィールドは、プロデューサ・メソッドの単純な代替です。

Java EE 8チュートリアルCDIアプリケーションでのプロデューサ・メソッド、プロデューサ・フィールドおよびディスポーザ・メソッドの使用に関する項を参照してください。

プロデューサ・メソッドの定義

プロデューサ・メソッドにより、アプリケーションはCDIマネージドBeanの作成方法をカスタマイズできます。このカスタマイズには、CDIがBeanを解決するために通常使用するプロセスのオーバーライドも含まれます。プロデューサ・メソッドにより、CDI Beanクラスのインスタンスではないオブジェクトを注入できるようになります。

プロデューサ・メソッドは、CDI BeanクラスまたはセッションBeanクラスのメソッドであることが必要です。ただし、プロデューサ・メソッドは、CDI Beanクラスのインスタンスではないオブジェクトを返すことができます。この状況では、プロデューサ・メソッドはBeanタイプが一致するオブジェクトを返す必要があります。

プロデューサ・メソッドには、任意の数のパラメータを指定できます。必要に応じて、これらのパラメータに修飾子を適用できます。プロデューサ・メソッドのすべてのパラメータは、注入ポイントです。したがって、プロデューサ・メソッドのパラメータには、@Injectアノテーションは必要ありません。

プロデューサ・メソッドを定義するには、javax.enterprise.inject.Producesアノテーションでメソッドの宣言に注釈付けします。

プロデューサ・メソッドがnullを返すことがある場合は、メソッドのスコープをDependentに設定します。

ノート:

アプリケーション・コードでプロデューサ・メソッドを直接コールしてもCDIは起動されません。

プロデューサ・メソッドの定義の例は、例9-11を参照してください。

ディスポーザ・メソッドの定義

プロデューサ・メソッドから返されるオブジェクトのカスタマイズ・クリーンアップが必要な場合は、プロデューサ・メソッドを宣言するクラスでディスポーザ・メソッドを定義します。

ディスポーザ・メソッドを定義するには、javax.enterprise.inject.Disposesアノテーションで、メソッドの宣言の破棄されるパラメータに注釈付けします。破棄されるパラメータのタイプは、プロデューサ・メソッドの戻りタイプと同じであることが必要です。

ディスポーザ・メソッドは、破棄されるオブジェクトの注入ポイントが、プロデューサ・メソッドのタイプと修飾子の両方に一致する場合に、プロデューサ・メソッドと一致します。1つのディスポーザ・メソッドをクラス内の複数のプロデューサ・メソッドに一致するように定義できます。

例9-11は、@Producesアノテーションを使用してプロデューサ・メソッドを定義する方法と、@Disposesアノテーションを使用してディスポーザ・メソッドを定義する方法を示しています。

例9-11 プロデューサ・メソッドとディスポーザ・メソッドの定義

この例では、プロデューサ・メソッドconnectとディスポーザ・メソッドcloseを定義します。

プロデューサ・メソッドconnectは、タイプConnectionのオブジェクトを返します。ディスポーザ・メソッドcloseでは、パラメータconnectionが、破棄されるパラメータです。このパラメータのタイプは、プロデューサ・メソッドの戻りタイプに一致するタイプConnectionです。

実行時に、CDIフレームワークによってSomeClassのインスタンスが作成され、プロデューサ・メソッドがコールされます。したがって、CDIフレームワークが、プロデューサ・メソッドに渡されるパラメータの注入を担当します。

プロデューサ・メソッドのスコープは@RequestScopedです。リクエスト・コンテキストが破棄されるときに、Connectionオブジェクトがそのリクエスト・コンテキストにある場合、CDIによってこのオブジェクトに対してディスポーザ・メソッドがコールされます。そのディスポーザ・メソッドへのコールでは、CDIによってConnectionオブジェクトがパラメータとして渡されます。

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.Disposes;

import javax.enterprise.context.RequestScoped;

public class SomeClass {
    @Produces @RequestScoped
    public Connection connect(User user) {
        return createConnection(user.getId(),
                user.getPassword());
    }
   
    private Connection createConnection(
            String id, String password) {...}
   
    public void close(@Disposes Connection connection) {
        connection.close();
    }
}

プロデューサ・フィールドの定義

プロデューサ・フィールドは、プロデューサ・メソッドの単純な代替です。プロデューサ・フィールドは、マネージドBeanクラスまたはセッションBeanクラスのフィールドにする必要があります。プロデューサ・フィールドは、次の制約に従って、静的である場合も静的でない場合もあります。

  • セッションBeanクラスでは、プロデューサ・フィールドは静的フィールドであることが必要です。

  • マネージドBeanクラスでは、プロデューサ・フィールドは、静的でも静的でなくても構いません。

プロデューサ・フィールドを定義するには、javax.enterprise.inject.Producesアノテーションでフィールドの宣言に注釈付けします。

プロデューサ・フィールドにアクセスしたときにnullが含まれている可能性がある場合は、フィールドのスコープをDependentに設定します。

ノート:

アプリケーション・コード内でプロデューサ・フィールドを直接使用すると、CDIは起動しません。

プロデューサ・フィールドには、ディスポーザはありません。

マネージドBeanの初期化と破棄の準備

CDIマネージドBeanクラスおよびそれらのスーパークラスでは、マネージドBeanの初期化と破棄の準備のためのアノテーションがサポートされています。

これらのアノテーションは、『JSR 250: Common Annotations for the Java Platform』で定義されています。詳細は、Java EEアノテーションと依存関係インジェクションの使用を参照してください。

マネージドBeanの初期化

マネージドBeanの初期化では、依存関係インジェクションの後、クラスがサービスを開始する前にCDIフレームワークがコールする必要があるライフ・サイクル・コールバック・メソッドを指定します。

マネージドBeanを初期化するには:

  1. マネージドBeanクラスまたはそのスーパークラスのいずれかで、必要な初期化を実行するメソッドを定義します。
  2. javax.annotation.PostConstructアノテーションで、メソッドの宣言に注釈付けします。

    マネージドBeanがコンポーネントに注入されると、すべての注入が実行され、すべてのイニシャライザがコールされた後にCDIによってそのメソッドがコールされます。

    ノート:

    JSR 250で規定されているように、注釈付けされたメソッドがスーパークラスで宣言される場合、宣言するクラスのサブクラスがそのメソッドをオーバーライドしないかぎり、そのメソッドがコールされます。

マネージドBeanの破棄の準備

マネージドBeanの破棄の準備では、アプリケーション・コンポーネントがコンテナによって破棄されようとしていることを通知するライフ・サイクル・コールバック・メソッドを指定します。

マネージドBeanの破棄を準備するには:

  1. マネージドBeanクラスまたはそのスーパークラスのいずれかで、マネージドBeanの破棄を準備するメソッドを定義します。

    このメソッドでは、Beanが保持していたリソースの解放など、Beanを破棄する前に必要なクリーンアップを実行します。

  2. javax.annotation.PreDestroyアノテーションで、メソッドの宣言に注釈付けします。

    Beanを破棄するためのロジックを開始する前にCDIによってそのメソッドがコールされます。

    ノート:

    JSR 250で規定されているように、注釈付けされたメソッドがスーパークラスで宣言される場合、宣言するクラスのサブクラスがそのメソッドをオーバーライドしないかぎり、そのメソッドがコールされます。

Beanクラスのメソッド呼出しおよびライフ・サイクル・イベントのインターセプト

Beanクラスのメソッド呼出しまたはライフ・サイクル・イベントのインターセプトでは、呼出しまたはイベントにインターセプタ・クラスを割り込みます。インターセプタ・クラスを割り込むと、そのインターセプタ・クラスで定義されている追加のアクションが実行されます。

インターセプタ・クラスによって、頻繁に実行されるが、アプリケーションのビジネス・ロジックからは分離されているタスクのコードのメンテナンスが簡素化されます。そのようなタスクの例としては、ロギングと監査があります。

ノート:

インターセプタ・クラスのプログラミング・モデルは、アプリケーションのビジネス・ロジックから分離されている操作に対して最適化されています。ビジネス・セマンティクスを持つ操作を実行するメソッドをインターセプトするには、「マネージドBeanクラスの装飾」の説明に従ってデコレータ・クラスを使用します

Java EE 5仕様で導入されたインターセプタは、EJBコンポーネント固有です。Java EE 5インターセプタの詳細は、『Oracle WebLogic Server Enterprise JavaBeansの開発』ビジネス・メソッドまたはライフ・サイクル・コールバック・イベントのインターセプタの指定に関する項 を参照してください。

CDIでは、次のタイプのJava EE管理対象オブジェクトでインターセプタを使用できます。

  • CDIマネージドBean

  • EJBセッションBean

  • EJBメッセージドリブンBean

ノート:

CDIではEJBエンティティBeanがサポートされていないため、EJBエンティティBeanでは、インターセプタを使用できません

Java EE 8チュートリアルCDIアプリケーションでのインターセプタの使用に関する項を参照してください。

Beanクラスのメソッド呼出しおよびライフ・サイクル・イベントのインターセプトには、次の項で説明するタスクが含まれます。

インターセプタ・バインディング・タイプの定義

インターセプタ・バインディング・タイプは、インターセプタ・クラスとインターセプトされるBeanを関連付けるアプリケーション定義のアノテーションです。必要なインターセプタのタイプごとにインターセプタ・バインディング・タイプを定義します。

ノート:

CDIでは、インターセプタ・バインディング・タイプが特定のインターセプタ・クラスに固有でなくても構いません。1つのインターセプタ・バインディング・タイプを複数のインターセプタ・クラスで使用するように定義できます。

インターセプタ・バインディング・タイプを定義するには:

  1. インターセプタ・バインディング・タイプを表すJavaアノテーション・タイプを定義します。
  2. javax.interceptor.InterceptorBindingアノテーションで、アノテーション・タイプの宣言に注釈付けします。
  3. インターセプタ・バインディング・タイプが、実行時に仮想マシンによって保持されることを指定します。

    このためには、java.lang.annotation.Retention(RUNTIME)メタアノテーションを使用します。

  4. インターセプタ・バインディング・タイプを、プログラム要素METHODおよびTYPEに適用できることを指定します。

    このためには、java.lang.annotation.Target({METHOD, TYPE})メタアノテーションを使用します。

例9-12 インターセプタ・バインディング・タイプの定義

この例では、@Transactionalインターセプタ・バインディング・タイプを定義します。

package com.example.billpayment.interceptor;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.interceptor.InterceptorBinding;

@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Transactional {}

インターセプタ・クラスの定義

インターセプタ・クラスは、関連付けられたターゲットBeanクラスで発生するメソッド呼出しまたはライフ・サイクル・イベントへの割込みに使用されます。インターセプタ・クラスでは、ロギングや監査など、頻繁に実行されるが、アプリケーションのビジネス・ロジックからは分離されているタスクのコードを提供します。

インターセプタ・クラスを定義するには:

  1. インターセプタを表すJavaクラスを定義します。
  2. 次のアノテーションでクラス宣言に注釈付けします。
    • javax.interceptor.Interceptor

    • クラスに対して定義されているインターセプタ・バインディング・タイプ

      1つのインターセプタ・クラスに、任意の数のインターセプタ・バインディング・タイプを適用できます。

      ノート:

      CDIでは、インターセプタ・バインディング・タイプが特定のインターセプタ・クラスに固有でなくても構いません。同じインターセプタ・バインディング・タイプを複数のインターセプタ・クラスに適用できます。

  3. そのクラス内にインターセプタ・メソッドを実装します。

    CDIでは、インターセプタ・メソッドのシグネチャがインターセプトされるメソッドのシグネチャに一致する必要はありません。

  4. クラス内のインターセプタ・メソッドを特定します。

    インターセプタ・メソッドは、Beanクラスのメソッド呼出しまたはライフ・サイクル・イベントをインターセプトするときに呼び出されるメソッドです。

    インターセプタ・メソッドを特定するには、インターセプタ・メソッドのタイプに適したアノテーションで、メソッドの宣言に注釈付けします。

    インターセプタ・メソッドのタイプ アノテーション

    メソッドの呼出し

    javax.interceptor.AroundInvoke

    EJBタイムアウト

    javax.interceptor.AroundTimeout

    マネージドBeanまたはEJBコンポーネントの初期化

    javax.annotation.PostConstruct

    マネージドBeanまたはEJBコンポーネントの破棄

    javax.annotation.PreDestroy

    ステートフル・セッションBeanのアクティブ化

    javax.ejb.PostActivate

    ステートフル・セッションBeanの非アクティブ化

    javax.ejb.PrePassivate

    ノート:

    1つのインターセプタ・クラスに、複数のインターセプタ・クラスを含めることができます。ただし、1つのインターセプタ・クラスに含めることができる特定のタイプのインターセプタ・メソッドは1つのみです。

例9-13は、インターセプタ・クラスを定義する方法を示します。

例9-13 インターセプタ・クラスの定義

この例では、@Transactionalインターセプタ・バインディング・タイプが定義されるインターセプタ・クラスを定義します。このクラスのmanageTransactionメソッドは、インターセプタ・メソッドです。@Transactionalインターセプタ・バインディングは、例9-12で定義されています。

package com.example.billpayment.interceptor;

import javax.annotation.Resource;
import javax.interceptor.*;
...
@Transactional @Interceptor
public class TransactionInterceptor {
    @Resource UserTransaction transaction;
    @AroundInvoke
    public Object manageTransaction(InvocationContext ctx)
            throws Exception {
        ...
    }
}

インターセプトのためのメソッドの特定

インターセプトのためのメソッドの特定により、メソッドと、そのメソッドが呼び出されるときに呼び出されるインターセプタが関連付けられます。CDIでは、インターセプトのためにBeanクラスのすべてのメソッドを特定するか、Beanクラスの個別のメソッドのみを特定できます。

  • インターセプトのためにBeanクラスのすべてのメソッドを特定するには、適切なインターセプタ・バインディング・タイプでBeanクラスの宣言に注釈付けします。

  • インターセプトのためにBeanクラスの個別のメソッドを特定するには、適切なインターセプタ・バインディング・タイプでそのメソッドの宣言に注釈付けします。

CDIでは、インターセプトされるメソッドのシグネチャがインターセプタ・メソッドのシグネチャに一致する必要はありません。インターセプトされるメソッドの引数と戻りタイプを判別するには、インターセプタがインターセプタ・コンテキストを問い合せる必要があります。したがって、Beanクラスのインタフェースのコンパイル時に何も知識がなくても、Beanクラスの任意のメソッドまたはライフ・サイクル・イベントをインターセプトできます。

ノート:

Java EE 5インターセプタの実装は、インターセプトされるメソッドのアノテーションで宣言する必要があります。CDIインターセプタは、インターセプタ・バインディングを使用して、インターセプタ・メソッドを特定し、インターセプトされるメソッドをそのインターセプタ・メソッドに関連付けます。インターセプトされるメソッドとインターセプタ・メソッドの両方に、バインディングで注釈付けする必要があります。このようにして、インターセプトされるメソッドとインターセプタ・メソッドは、インターセプタ・バインディングを介してのみ相互に関連付けされます。

例9-14 インターセプトのためのBeanクラスのすべてのメソッドの特定

この例では、@Transactionalインターセプタによって、インターセプトのためのShoppingCartクラスのすべてのメソッドが特定されます。

package com.example.billpayment.interceptor;

@Transactional
public class ShoppingCart {
    ...
}

例9-15 インターセプトのためのクラスの個別のメソッドの特定

この例では、@Transactionalインターセプタによって、インターセプトのためのShoppingCartクラスのcheckoutメソッドのみが特定されます。

package com.example.billpayment.interceptor;

public class ShoppingCart {
    ...
    @Transactional public void checkout() {
    ...
    }
}

インターセプタの有効化

デフォルトでは、インターセプタは無効です。インターセプタを、メソッドの呼出しおよびイベントに割り込む必要がある場合は、インターセプタを明示的に有効化する必要があります。

インターセプタを有効化するには:

  1. beans.xmlファイルのinterceptors要素にインターセプタのclass要素を追加します。
  2. class要素に、そのインターセプタの完全修飾クラス名を指定します。

    beans.xmlファイル内のclass要素の順序が、インターセプタの呼出し順序と一致するようにします。

    CDIインターセプタは、beans.xmlファイルで宣言されている順序で呼び出されます。ejb-jar.xmlファイル内またはjavax.interceptor.Interceptorsアノテーションによって定義されているインターセプタは、CDIインターセプタの前にコールされます。インターセプタは、CDIデコレータの前にコールされます。

    ノート:

    Java EE 5インターセプタは、インターセプトされるメソッドで注釈付けされている順序で呼び出されます。

beans.xmlファイルの詳細は、「CDIアプリケーションの構成」を参照してください

例9-16は、インターセプタ・クラスを有効化するためのbeans.xmlファイルのclass要素を示します。

例9-16 インターセプタ・クラスの有効化

この例では、インターセプタ・クラスcom.example.billpayment.interceptor.TransactionInterceptorを有効化します。インターセプタ・クラスは、例9-13で定義されています。

...
<interceptors>
    <class>com.example.billpayment.interceptor.TransactionInterceptor</class>
</interceptors>
...

プロデューサへのインターセプタの適用

CDI 1.xでは、インターセプタはプロデューサBeanにバインドされません。CDI 2.0では、インタフェースjavax.enterprise.inject.spi.InterceptionFactory<T>が導入され、それにより、インターセプタをプロデューサ・メソッドの戻り値にプログラムで適用できるようになります。

InterceptionFactoryインタフェースを使用すると、メソッド呼出しがメソッド・インターセプタによってインターセプトされ、指定されたインスタンスに転送されるラッパー・インスタンスを作成できます。

publicinterfaceInterceptionFactory<T> {
    InterceptionFactory<T> ignoreFinalMethods();
    AnnotatedTypeConfigurator<T> configure();
    T createInterceptedInstance(T instance);
}

BeanManager.createInterceptionFactory()を呼び出して、InterceptionFactoryの実装を取得できます。次の例は、InterceptionFactoryを使用したプロデューサ・メソッドを示しています。

@Produces
@RequestScoped
public Product createInterceptedProduct(InterceptionFactory<Product> interceptionFactory) {
  interceptionFactory.configure().add(ActionBinding.Literal.INSTANCE);
  return interceptionFactory.createInterceptedInstance(new Product());
}

インターセプタの使用の詳細は、Java EE 8チュートリアルCDIアプリケーションでのインターセプタの使用に関する項を参照してください。

マネージドBeanクラスの装飾

マネージドBeanクラスの装飾により、ビジネス・セマンティクスを持つ操作を実行する装飾されるクラスのメソッドの呼出しをインターセプトできます。

どのマネージドBeanクラスも装飾できます。

ノート:

デコレータ・クラスのプログラミング・モデルは、アプリケーションのビジネス・ロジックを実行する操作に対して最適化されています。アプリケーションのビジネス・ロジックから分離されているメソッドをインターセプトするには、「Beanクラスのメソッド呼出しおよびライフ・サイクル・イベントのインターセプト」の説明に従ってインターセプタ・クラスを使用します

Java EE 8チュートリアルデコレータの使用に関する項を参照してください。

マネージドBeanクラスの装飾には、次の項で説明するタスクが含まれます。

デコレータ・クラスの定義

デコレータ・クラスは、ビジネス・セマンティクスを持つ操作を実行する装飾されるクラスのメソッドの呼出しをインターセプトします。デコレータ・クラスおよびインターセプタ・クラスは類似しており、どちらもメソッド周辺のインターセプトを提供します。ただし、デコレータ・クラスのメソッドは、装飾されるBeanクラスのインターセプトされるメソッドと同じシグネチャを持ちます。

デコレータ・クラスを定義するには:

  1. 装飾対象のBeanクラスと同じインタフェースを実装するJavaクラスを作成します。

    装飾されるクラスのいくつかのメソッドのみをインターセプトする場合は、デコレータ・クラスを抽象クラスとして宣言します。クラスを抽象として宣言する場合、装飾対象のBeanクラスのすべてのメソッドを実装する必要はありません。

  2. javax.decorator.Decoratorアノテーションでデコレータ・クラスのクラス宣言に注釈付けします。

  3. インターセプトする装飾されるBeanクラスのメソッドを実装します。

    デコレータ・クラスが具体クラスである場合、装飾するBeanクラスのすべてのメソッドを実装する必要があります。

    デコレータ・クラスのインターセプトするメソッドが、装飾されるBeanクラスのインターセプトされるメソッドと同じシグネチャを持つようにしてください。

  4. デコレータ・クラスに委任注入ポイントを追加します。

    デコレータ・クラスには、委任注入ポイントが1つのみ含まれている必要があります。委任注入ポイントは、装飾されるクラスのインスタンスである委任オブジェクトを、デコレータ・オブジェクトに注入します。

    デコレータ・オブジェクトのメソッドが、装飾されるメソッドの実装を処理する方法をカスタマイズできます。CDIでは、デコレータ・オブジェクトが、対応する委任オブジェクトを呼び出すことができますが、これは必須ではありません。したがって、デコレータ・オブジェクトに、対応する委任オブジェクトを呼び出させるかどうかは自由に選択できます。

    1. デコレータ・クラスで、装飾するBeanクラスのインスタンスを注入します。

    2. javax.decorator.Delegateアノテーションで、注入ポイントに注釈付けします。

    3. 注入ポイントに修飾子を適用する必要がある場合は、適用します。

      注入ポイントに修飾子を適用すると、デコレータは、注入ポイントの修飾子に一致するBeanクラスのBeanにのみ適用されます。

ノート:

装飾されるBeanクラスを定義するために、アノテーションなどの特別な宣言は必要ありません。有効化されたデコレータ・クラスは、委任注入ポイントのBeanタイプと修飾子に一致するBeanクラスまたはセッションBeanに適用されます。

例9-17は、デコレータ・クラスの定義を示します。

例9-17 デコレータ・クラスの定義

この例では、デコレータ・クラスDataAccessAuthDecoratorを定義します。このクラスは、タイプDataAccessのBeanを装飾します。

装飾されるクラスのいくつかのメソッドのみがインターセプトされるため、このクラスは抽象クラスとして宣言します。このクラスは、DataAcess Beanタイプの装飾される実装の委任インスタンスdelegateを注入します。

import javax.decorator.*;
import javax.inject.Inject;
import java.lang.Override;
...
@Decorator
public abstract class DataAccessAuthDecorator
        implements DataAccess {
       
    @Inject @Delegate DataAccess delegate;
 
    @Override
    public void delete(Object object) {
        authorize(SecureAction.DELETE, object);
        delegate.delete(object);
    }
 
    private void authorize(SecureAction action, Object object) {
        ...
    }
}

デコレータ・クラスの有効化

デフォルトでは、デコレータ・クラスは無効です。CDIアプリケーションで、デコレータ・クラスを呼び出す必要がある場合は、デコレータ・クラスを明示的に有効化する必要があります。

デコレータ・クラスを有効化するには:

  1. beans.xmlファイルのdecorators要素に、デコレータ・クラスのclass要素を追加します。
  2. class要素に、そのデコレータ・クラスの完全修飾クラス名を指定します。

    beans.xmlファイル内のclass要素の順序が、デコレータ・クラスの呼出し順序と一致するようにします。

ノート:

アプリケーションに対して定義されているインターセプタ・クラスは、そのアプリケーションのデコレータ・クラスの前に呼び出されます。

beans.xmlファイルの詳細は、「CDIアプリケーションの構成」を参照してください

例9-18は、デコレータ・クラスを有効化するためのbeans.xmlファイルのclass要素を示します。

例9-18 デコレータ・クラスの有効化

この例では、デコレータ・クラスcom.example.billpayment.decorator.DataAccessAuthDecoratorを有効化します。

...
<decorators>
     <class>com.example.billpayment.decorator.DataAccessAuthDecorator</class>
</decorators>
...

CDI BeanクラスへのEL名の割当て

ELにより、プレゼンテーション・レイヤーのコンポーネントが、アプリケーション・ロジックを実装するマネージドBeanと通信できます。

プレゼンテーション・レイヤーのコンポーネントは、通常、JavaServer Faces (JSF)ページおよびJavaServer Pages (JSP)ページです。『Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』JSP式言語に関する項を参照してください。

JSPページおよびJSFページのスクリプト言語では、注入される変数の構文は、これらの言語の組込み変数の構文と同一です。JSPページまたはJSFページに注入されるCDI Beanは、EL名を介してアクセス可能であることが必要です。Java EE 8チュートリアルBeanのEL名の指定に関する項を参照してください。

EL名をCDI Beanクラスに割り当てるには、javax.inject.NamedアノテーションでBeanクラスのクラス宣言に注釈付けします。

名前を指定しない場合、EL名は、最初の文字を小文字にした非修飾クラス名です。たとえば、非修飾クラス名がShoppingCartである場合、EL名はshoppingCartです。

名前を指定するには、@Namedアノテーションのvalue要素を、目的の名前に設定します。

ノート:

EL名をCDI Beanクラスに割り当てるには、@NamedアノテーションでBeanクラス宣言に注釈付けする必要があります。クラスに@Namedで注釈付けされていない場合、CDI BeanクラスにEL名は付きません。

次の例は、@Namedアノテーションを使用してEL名をCDI Beanクラスに割り当てる方法を示します。この例では、EL名cartShoppingCartクラスに割り当てます。

import javax.enterprise.context.SessionScoped;


@SessionScoped
@Named("cart")
public class ShoppingCart {
    public String getTotal() {
       ...
    }
   
    ...
}

JSPページまたはJSFページがアクセスするBeanは、JavaBeans標準に準拠している必要があります。BeanのEL名を介してJSPページまたはJSFページからCDIマネージドBeanにアクセスするには、JavaBeansコンポーネントの構文に類似した構文を使用します。

次の例は、JSFページで、ShoppingCartクラスのインスタンスに、そのクラスに割り当てられたEL名を介してアクセスする方法を示しています。

例9-19 EL名を介したBeanへのアクセス

この例では、ShoppingCartクラスのインスタンスにアクセスし、JSFページにそのtotalプロパティの値を表示します。

このプロパティは、ShoppingCartクラスのgetTotal getterメソッドによって返されます。

...
<h:outputText value="#{cart.total}"/>
...

ステレオタイプの定義と適用

いくつかのBeanが類似した関数を実行する大規模なアプリケーションでは、場合によっては、同じアノテーションのセットをいくつかのBeanクラスに適用する必要があります。ステレオタイプを定義すると、アノテーションのセットの定義を一度行うのみで済みます。

その後、そのステレオタイプを使用して、同じアノテーションのセットを、それらのアノテーションを必要とするすべてのBeanクラスに適用できるようになります。Java EE 8チュートリアルステレオタイプの使用に関する項を参照してください。

ステレオタイプの定義と適用には、次の項で説明するタスクが含まれます。

ステレオタイプの定義

ステレオタイプは、アプリケーション定義のアノテーション・タイプであり、他のアノテーション・タイプが組み込まれています。

ステレオタイプを定義するには:

  1. ステレオタイプを表すJavaアノテーション・タイプを定義します。
  2. 次のアノテーションでアノテーション・タイプの宣言に注釈付けします。
  3. ステレオタイプが、実行時に仮想マシンによって保持されることを指定します。

    このためには、java.lang.annotation.Retention(RUNTIME)メタアノテーションを使用します。

  4. ステレオタイプをプログラム要素TYPEに適用できることを指定します。

    このためには、java.lang.annotation.Target(TYPE)メタアノテーションを使用します。

次の例では、ステレオタイプの定義を示します。

例9-20 ステレオタイプの定義

この例では、ステレオタイプ@Actionを定義します。これは、ステレオタイプが注釈付けする各Beanに対して次のことを指定します。

  • デフォルトのスコープは、そのスコープがスコープ・アノテーションでオーバーライドされていないかぎり、Requestスコープです。

  • その名前が@Namedアノテーションでオーバーライドされていないかぎり、デフォルトEL名がBeanに割り当てられます。

  • インターセプタ・バインディング@Secureおよび@TransactionalがBeanに適用されます。これらのインターセプタ・バインディングの定義は、この例の範囲外です。

import javax.enterprise.inject.Stereotype;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped; 
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@RequestScoped
@Secure
@Transactional
@Named
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}

Beanへのステレオタイプの適用

Beanにステレオタイプを適用するには、適用する各ステレオタイプで、そのBeanのクラス宣言に注釈付けします。Beanには任意の数のステレオタイプを適用できます。Beanに適用するステレオタイプは、「ステレオタイプの定義」の説明に従って定義する必要があります

例9-21は、Beanにステレオタイプを適用する方法を示します。

例9-21 Beanへのステレオタイプの適用

この例では、ステレオタイプ@Actionおよび@MockをBeanクラスMockLoginActionに適用します。@Actionステレオタイプの定義を、例9-20に示します。@Mockステレオタイプの定義は、この例の範囲外です。

@Action
@Mock
public class MockLoginAction extends LoginAction {
 ... 
}

Bean間の通信のためのイベントの使用方法

イベントを使用すると、Beanはコンパイル時の依存関係なしに情報を通信できます。

実行時に、アプリケーションで、情報を生成する処理が実行されたり、状態の変更が発生し、Bean間の通信が必要となる場合があります。たとえば、アプリケーションで、アプリケーションのアーキテクチャの1つの層のステートフルBeanがそれらの内部状態を、別の層で発生する状態の変更と同期することが必要な場合があります。

イベントを使用すると、Beanはコンパイル時の依存関係なしにこの情報を通信できます。1つのBeanでイベントを定義し、別のBeanでイベントを送信し、さらに別のBeanでそのイベントを処理できます。これらのBeanは、それぞれ別のパッケージに含めることができ、アプリケーションの別の層に含めることもできます。Java EE 8チュートリアルイベントの使用に関する項を参照してください。

Bean間の通信のためのイベントの使用には、次の項で説明するタスクが含まれます。

イベント・タイプの定義

イベント・タイプは、Bean間で通信する情報を表すJavaクラスです。たとえば、イベント・タイプは、ステートフルBeanがアプリケーションの別の層における状態の変更と同期する必要がある状態情報を表す場合があります。

Bean間で通信する変更のセットごとにイベントのタイプを定義します。

イベント・タイプを定義するには:

  1. そのイベント・タイプを表すJavaクラスを定義します。

    そのクラスが、次の要件を満たすようにします。

    • クラスが具体Javaクラスとして宣言されています。

    • クラスにタイプ変数がありません。

      イベントのイベント・タイプには、イベント・オブジェクトのランタイム・クラスのすべてのスーパークラスとインタフェースが含まれます。イベント・タイプには、タイプ変数を含めないでください。どのJavaタイプも監視対象のイベント・タイプにできます。

  2. 必要であれば、このタイプのイベントをさらに区別するための修飾子を定義します。詳細は、「Beanタイプの実装に対する修飾子の定義」を参照してください
  3. クラスにコードを指定して、クラスからインスタンス化されるイベント・オブジェクトのイベント・ペイロードを移入します。

    イベント・ペイロードとは、そのイベントに含める情報です。getterおよびsetterメソッドとともにJavaBeansプロパティを使用して、イベント・ペイロード内の情報のアイテムを表すことができます。

イベントの送信

処理に応じて発生した変更を通信するには、アプリケーションが、処理を実行するときに正しいタイプのイベントを送信する必要があります。CDIは、実行時にアプリケーション・コードがイベントを送信し、関連付けられた修飾子を選択できるようにする事前定義済イベント・ディスパッチャ・オブジェクトを提供しています。

イベントを送信するには:

  1. 送信するイベント・タイプのインスタンスを取得します。
  2. 送信するイベント・オブジェクトのイベント・ペイロードを移入するためのイベント・インスタンスのメソッドをコールします。
  3. パラメータ化javax.enterprise.event.Eventインタフェースのインスタンスを注入します。

    修飾イベントを送信する場合、イベント修飾子で注入ポイントに注釈付けします。

  4. 注入されるEventインスタンスのfireメソッドをコールします。
    • fireメソッドへのコールで、送信するイベント・インスタンスをパラメータとして渡します。このメソッドは、イベントを同期的に起動し、オブザーバ・メソッドに通知します。

    • fireAsync()メソッドを使用すると、イベントを非同期に起動できます。このメソッドの呼出しはただちに返され、オブザーバ・メソッドは非同期に通知されます。Java EE 8チュートリアルイベントの起動に関する項を参照してください。

例9-22は、イベントを送信する方法を示します。

例9-22 イベントの送信

この例では、修飾子@LoggedInで、タイプUserのイベントのインスタンスを注入します。fireメソッドは、@LoggedIn修飾子が適用されるUserイベントのみを送信します。

import javax.enterprise.event.Event;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import java.io.Serializable;

@SessionScoped
public class Login implements Serializable {
 
    @Inject @LoggedIn Event<User> userLoggedInEvent;
    private User user;
   
    public void login(Credentials credentials) {
   
        //... use credentials to find user
       
        if (user != null) {
            userLoggedInEvent.fire(user);
        }
    }
    ...
}

イベントの処理

どのCDIマネージドBeanクラスもイベントを処理できます。

イベントを処理するには:

  1. Beanクラスでは、イベントを処理するメソッドを定義します。

    ノート:

    修飾子をイベント・タイプに適用する場合、修飾されるタイプごとに1つのメソッドを定義します。

  2. メソッドのシグネチャで、メソッドにイベントを渡すためのパラメータを定義します。

    パラメータのタイプは、必ずイベントのJavaタイプと同一になるようにします。

  3. javax.enterprise.event.Observesアノテーションで、メソッド・シグネチャのパラメータに注釈付けします。
    必要であれば、
    • @Priorityアノテーションを使用してオブザーバ・メソッドの順序を設定し、イベントのオブザーバ・メソッドが呼び出される順序を指定します。Java EE 8チュートリアルオブザーバ・メソッドの順序付けに関する項を参照してください。

  4. イベント・タイプが修飾されている場合は、注釈付けされるパラメータに修飾子を適用します。
  5. メソッド本体に、イベント・オブジェクトのイベント・ペイロードを処理するためのコードを指定します。

例9-23は、特定のタイプの修飾されたイベントを受信するためのオブザーバ・メソッドを宣言する方法を示します。例9-24は、特定のタイプのすべてのイベントを受信するためのオブザーバ・メソッドを宣言する方法を示します。

例9-23 特定のタイプの修飾されたイベントの処理

この例では、@Observesアノテーションと@LoggedIn修飾子でパラメータuserが注釈付けされているafterLoginメソッドを宣言します。このメソッドは、修飾子@LoggedInが付いたタイプUserのイベントが送信されるときにコールされます。

import javax.enterprise.event.Observes;

    public void afterLogin(@Observes @LoggedIn User user) {
        ...
    }

例9-24 特定のタイプのイベントの処理

この例では、@Observesアノテーションでパラメータuserが注釈付けされているafterLoginメソッドを宣言します。このメソッドは、タイプUserのイベントが送信されるときにコールされます。

import javax.enterprise.event.Observes;

    public void afterLogin(@Observes User user) {
        ...
    }

事前定義済Beanの注入

事前定義済Beanは、Dependentスコープおよび事前定義済のデフォルト修飾子@Defaultが指定されて注入されます。

CDIは、次のインタフェースを実装する事前定義済Beanを提供しています。

javax.transaction.UserTransaction

Java Transaction API (JTA)ユーザー・トランザクション。

java.security.Principal

個人、企業、ログインIDなどのエンティティを表すプリンシパルの抽象的な観念。

プリンシパルは、現在のコール元のIDを表します。注入されたプリンシパルにアクセスする場合はいつでも、それは常に現在のコール元のIDを表します。

たとえば、プリンシパルは、初期化の際にフィールドに注入されます。後で、プリンシパルが注入されたオブジェクトに対して、注入されたプリンシパルを使用するメソッドがコールされます。この状況では、注入されたプリンシパルは、メソッドが実行されるときの現在のコール元のIDを表します。

javax.validation.Validator

Beanインスタンスのバリデータ。

このインタフェースを実装するBeanによって、デフォルトのBean検証ValidatorFactoryオブジェクトのValidatorオブジェクトを注入できます。

javax.validation.ValidatorFactory

初期化されたValidatorインスタンスを返すファクトリ・クラス。

このインタフェースを実装するBeanによって、デフォルトのBean検証ValidatorFactoryオブジェクトを注入できます。

事前定義済Beanを注入するには、javax.annotation.Resourceアノテーションを使用して、Beanのインスタンスを取得することで、注入ポイントを作成します。Beanタイプについては、Beanによって実装されるインタフェースのクラス名を指定します。

事前定義済Beanは、Dependentスコープおよび事前定義済のデフォルト修飾子@Defaultが指定されて注入されます。

リソースの注入の詳細は、Java EE 8チュートリアルリソースの注入に関する項を参照してください。

例9-25は、@Resourceアノテーションを使用して事前定義済Beanを注入する方法を示します。

例9-25 事前定義済Beanの注入

この例では、サーブレット・クラスTransactionServletにユーザー・トランザクションを注入します。ユーザー・トランザクションは、javax.transaction.UserTransactionインタフェースを実装する事前定義済Beanのインスタンスです。

import javax.annotation.Resource;
import javax.servlet.http.*;
...
public class TransactionServlet extends HttpServlet {
    @Resource UserTransaction transaction;
        ...
}

リソースの注入と修飾

Java EE 5のリソース注入は、構成の文字列に依存しています。通常、これらの文字列は、オブジェクトが作成されるときに解決されるJNDI名です。CDIでは、注入ポイントで指定されているJavaタイプに基づいてBeanクラスを選択することで、Beanの型保証注入が保証されます。

CDI Beanクラスでも、データ・ソース、Java Message Service (JMS)リソース、Webサービス参照など実際のリソースにアクセスするには、Java EE 5のリソース注入が必要です。CDI Beanクラスは、Java EE 5のリソース注入を使用できるため、プロデューサ・フィールドを使用して、Java EE 5のリソース注入への依存を最小限にできます。このようにすることで、CDIでは、適切なリソースにアクセスするために必要な構成をカプセル化する方法が簡素化されます。

Java EE 5のリソース注入への依存を最小限にするには:

  1. アプリケーション内の1箇所のみで、Java EE 5のリソース注入を使用します。

  2. プロデューサ・フィールドを使用して、注入されるリソース・タイプをCDI Beanに変換します。

    このCDI Beanは、他のCDI Beanと同様にアプリケーションに注入できます。

    プロデューサ・フィールドの詳細は、「プロデューサ・フィールドの定義」を参照してください

次の例は、Java EE 5アノテーションを使用してリソースを注入する方法を示します。
import javax.annotation.Resource;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.ejb.EJB;
import javax.xml.ws.WebServiceRef;
...
public class SomeClass {
 
    @WebServiceRef(lookup="java:app/service/PaymentService")
    PaymentService paymentService;
   
    @EJB(ejbLink="../payment.jar#PaymentService")
    PaymentService paymentService;
   
    @Resource(lookup="java:global/env/jdbc/CustomerDatasource")
    Datasource customerDatabase;
   
    @PersistenceContext(unitName="CustomerDatabase")
    EntityManager customerDatabasePersistenceContext;
   
    @PersistenceUnit(unitName="CustomerDatabase")
    EntityManagerFactory customerDatabasePersistenceUnit;
   
    ...
}

次の例は、CDIプロデューサ・フィールドとJava EE 5のリソース注入を結合することで、同じリソースのセットを注入する方法を示します。

SomeClassクラスの宣言は、このBeanのスコープをApplicationに設定する@ApplicationScopedで注釈付けされています。@Dependentスコープは、プロデューサ・フィールドに暗黙的に適用されます。
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.annotation.Resource;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.ejb.EJB;
javax.xml.ws.WebServiceRef;
...
@ApplicationScoped
public class SomeClass {
 
    @Produces
    @WebServiceRef(lookup="java:app/service/PaymentService")
    PaymentService paymentService;
   
    @Produces
    @EJB(ejbLink="../their.jar#PaymentService")
    PaymentService paymentService;
   
    @Produces @CustomerDatabase
    @Resource(lookup="java:global/env/jdbc/CustomerDatasource")
    Datasource customerDatabase;
   
    @Produces @CustomerDatabase
    @PersistenceContext(unitName="CustomerDatabase")
    EntityManager customerDatabasePersistenceContext;
   
    @Produces @CustomerDatabase
    @PersistenceUnit(unitName="CustomerDatabase")
    EntityManagerFactory customerDatabasePersistenceUnit;
    ...
}

CDIでは、CDIとの一貫性を保つようにCDIアプリケーションでJava EEリソースを使用できます。このようにJava EEリソースを使用するには、そのリソースをCDI Beanとして他のBeanに注入します。

次の例は、Java EEリソースをCDI Beanとして別のBeanに注入する方法を示します。

この例では、永続性ユニット・リソースをRequestスコープを持つBeanに注入します。
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Inject;

@RequestScoped
public class SomeOtherClass { 
    ...
    @Inject @CustomerDatabase
    private EntityManagerFactory emf;
    ...
}

別のクラス、たとえばYetAnotherClassは、タイプSomeOtherClassのフィールドを注入できます。SomeOtherClassのインスタンスが、現在のリクエスト・コンテキストに存在していない場合は、CDIによって次の一連の処理が実行されます。

  1. SomeOtherClassのインスタンスの作成

  2. プロデューサ・フィールドを使用することによるエンティティ・マネージャ・ファクトリへの参照の注入

  3. 現在のリクエスト・コンテキストでのSomeOtherClassの新しいインスタンスの保存

どの場合も、CDIによって、SomeOtherClassのこのインスタンスへの参照が、YetAnotherClassのフィールドに注入されます。リクエスト・コンテキストが破棄されるときに、SomeOtherClassのインスタンスおよびエンティティ・マネージャ・ファクトリへのその参照が破棄されます。

JCAテクノロジでのCDIの使用方法

WebLogic Serverでは、埋込みリソース・アダプタおよびグローバル・リソース・アダプタでのCDIがサポートされています。CDIに対してリソース・アダプタを有効化するには、リソース・アダプタのパッケージ化されたアーカイブのMETA-INFディレクトリにbeans.xmlファイルを配置します。

beans.xmlファイルの詳細は、「CDIアプリケーションの構成」を参照してください

リソース・アダプタのすべてのクラスを、注入に使用できます。次のクラスを除いて、リソース・アダプタのすべてのクラスをCDIマネージドBeanにできます。

  • リソース・アダプタBean。これらのBeanは、javax.resource.spi.Connectorアノテーションで注釈付けされているか、リソース・アダプタ・デプロイメント記述子ra.xmlで対応する要素として宣言されているクラスです。

  • マネージド接続ファクトリBean。これらのBeanは、javax.resource.spi.ConnectionDefinitionアノテーションまたはjavax.resource.spi.ConnectionDefinitionsアノテーションで注釈付けされているか、ra.xmlで対応する要素として宣言されているクラスです。

  • アクティブ化仕様Bean。これらのBeanは、javax.resource.spi.Activationアノテーションで注釈付けされているか、ra.xmlで対応する要素として宣言されてるクラスです。

  • 管理対象オブジェクトBean。これらのBeanは、javax.resource.spi.AdministeredObjectアノテーションで注釈付けされているか、ra.xmlで対応する要素として宣言されているクラスです。

CDIアプリケーションの構成

CDIアプリケーションを構成することにより、アプリケーションのCDIサービスが有効になります。CDIアプリケーションを構成して、アプリケーションをCDIアプリケーションとして識別する必要があります。CDIマネージドBeanを定義するために、アノテーションなどの特別な宣言は必要ありません。CDIアプリケーションのパッケージ化のために特に定義されているモジュール・タイプはありません。

CDIアプリケーションを構成するには、beans.xmlという名前のファイルを、アプリケーションのパッケージ化されたアーカイブに含めます。beans.xmlファイルは、eXtensible Markup Language (XML)スキーマbeans_2_0.xsdのインスタンスである必要があります。

アプリケーションで代替、インターセプタ、デコレータのいずれも使用しない場合は、beans.xmlファイルを空にできます。ただし、beans.xmlファイルは空であっても提供する必要があります。

CDIアプリケーションで代替、インターセプタまたはデコレータを使用する場合は、それらのアイテムをbeans.xmlファイルで宣言することでそれらを有効化する必要があります。詳細は、次を参照してください:

beans.xmlファイルの必須の場所は、アプリケーションのタイプに応じて異なります。

  • Webアプリケーションの場合は、beans.xmlファイルは、WEB-INFディレクトリ内に配置してください。

  • EJBモジュール、リソース・アーカイブ(RAR)ファイル、アプリケーション・クライアントJARファイル、またはライブラリJARファイルの場合は、beans.xmlファイルはMETA-INFディレクトリ内に配置してください。

CDI Beanアーカイブは、EJBモジュールのlibディレクトリに含めることができます。EJBモジュールのlibディレクトリの各CDI BeanアーカイブのMETA-INFディレクトリにbeans.xmlファイルを含める必要があります。

例9-26は、CDIアプリケーションを構成するためのbeans.xmlファイルを示します。

例9-26 CDIアプリケーションを構成するためのbeans.xmlファイル

この例では、次のクラスを有効化することで、CDIアプリケーションを構成します。

  • 代替の実装com.example.orderprocessor.MockOrderImpl

  • インターセプタ・クラスcom.example.billpayment.interceptor.TransactionInterceptor

  • デコレータ・クラスcom.example.billpayment.decorator.DataAccessAuthDecorator

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee 
      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
<alternatives>
    <class>com.example.orderprocessor.MockOrderImpl</class>
</alternatives>
<interceptors>
    <class>com.example.billpayment.interceptor.TransactionInterceptor</class>
</interceptors>
<decorators>
    <class>com.example.billpayment.decorator.DataAccessAuthDecorator</class>
</decorators>
</beans>

CDIの有効化および無効化

ドメインのCDIはデフォルトで有効になっています。 ただし、CDIを使用しない場合でも、WebLogic Serverでアプリケーションをデプロイする際に発生するCDIの初期化がいくつかあります。 CDIを使用しないアプリケーションのデプロイメント・パフォーマンスを最大化するために、CDIを無効にすることができます。

CDIコンテナでPolicyパラメータを設定することにより、ドメイン内でCDIを有効にするかどうかを制御できます。このパラメータがEnabledに設定されている場合、CDIはドメイン内のすべてのアプリケーションで有効です。PolicyパラメータがDisabledに設定されている場合、CDIはドメイン内のすべてのアプリケーションで無効です。 

1つのドメインに対してのみCDIを無効にすることができます。

1つのドメインに対するCDIの有効化および無効化

ドメインにデプロイされるすべてのアプリケーションに対してCDIを無効化するには、 config.xmlファイルに次の行を追加します。

<domain>
<cdi-container>
<policy>Disabled</policy>
</cdi-container>
<domain>

WLSTスクリプト・ツールを使用してドメインに対するCDIを有効化または無効化できます。次の例は、WLSTを使用してオンラインまたはオフラインでドメインに対するCDIを有効化または無効化する方法を示します。

例9-27 オンライン時のCDIの有効化

次の例では、WebLogic Serverが稼働しています。引数usernameおよびpasswordは、サーバーにWLSTを接続しているユーザーの資格証明を表し、urlは、サーバー・インスタンスのリスニング・アドレスおよびリスニング・ポートを表します(たとえば、localhost:7001)。また、domainはドメイン名を表す必要があります。

connect('user','password','url')
 domainConfig()
 edit()
 cd('CdiContainer/mydomain')
 startEdit()
 set('Policy','Enabled') // 'Enabled' or 'Disabled'
 validate()
 save()
 activate(block="true")

例9-28 オフライン時のCDIの有効化

次の例では、domainはドメインのパスを表します(たとえば、/oracle/wls/mydomain)。また、mydomainはドメイン名と一致する必要があります。


readDomain('domain')
create('mydomain','CdiContainer')
cd('CdiContainer/mydomain')
set('Policy','Enabled') // 'Enabled' or 'Disabled' 
updateDomain()
 closeDomain()

暗黙的Beanの検出

CDI 1.1およびJava EE 7では、暗黙的Beanアーカイブの概念を導入しました。暗黙的Beanアーカイブは、beans.xmlファイルを持たないJARファイルまたはWARファイルのアーカイブです。CDIによって管理できるBeanを持ちます。

これは、アプリケーションをデプロイするのにかかる時間を大幅に増やす可能性があります。この時間の増加は、Java EE 7より前のリリース用に作成され、Java EE 7アプリケーション・サーバーにデプロイされたアプリケーションで特に顕著です。CDI 1.0との互換性を持つために、WebLogic Serverにはbeans.xmlファイルがない場合でもコンテナでアーカイブを無視するように設定するオプションが含まれています。

CDIコンテナでimplicit-bean-discovery-enabledパラメータを設定して、暗黙的Beanの検出が有効かどうかをドメインで制御します。このパラメータが1に設定されている場合、暗黙的Beanの検出はドメイン内のすべてのアプリケーションで有効化されます。implicit-bean-discovery-enabledパラメータが0に設定されている場合、暗黙的Beanの検出はドメイン内のすべてのアプリケーションに対して無効です。 

1つのドメインに対してのみ暗黙的Beanの検出を無効にできます。

1つのドメインに対する暗黙的Beanの検出の有効化および無効化

ドメインにデプロイされるすべてのアプリケーションに対して暗黙的Beanの検出を無効化するには、config.xmlファイルに次の行を追加します。

<domain>
<cdi-container>
<implicit-bean-discovery-enabled>false</implicit-bean-discobery-enabled>
</cdi-container>
<domain>

WLSTスクリプト・ツールを使用してこの機能を有効化または無効化できます。次の例は、WLSTを使用してオンラインまたはオフラインでドメインに対する暗黙的Beanの検出を有効化または無効化する方法を示します。

例9-29 WLSTをオンラインで使用した暗黙的Beanの検出の有効化

次の例では、WebLogic Serverが稼働しています。引数usernameおよびpasswordは、サーバーにWLSTを接続しているユーザーの資格証明を表し、urlは、サーバー・インスタンスのリスニング・アドレスおよびリスニング・ポートを表します(たとえば、localhost:7001)。また、domainはドメイン名を表す必要があります。

connect('user','password','url')
domainConfig()
edit()
cd('CdiContainer/mydomain')
startEdit()
set('ImplicitBeanDiscoveryEnabled',1)  // 1 to enable 0 to disable
validate()
save()
activate(block="true")

例9-30 WLSTをオフラインで使用した暗黙的Beanの検出の有効化

次の例では、domainはドメインのパスを表します(たとえば、/oracle/wls/mydomain)。また、mydomainはドメイン名と一致する必要があります。

readDomain(domain)
create('mydomain','CdiContainer')
cd('CdiContainer/mydomain')
set('ImplicitBeanDiscoveryEnabled',1)
// 1 to enable 0 to disable
updateDomain()
closeDomain()

サード・パーティのポータブルな拡張のサポート

CDIは、フレームワーク、拡張、および他のテクノロジとの統合の基盤となることを目的としています。

CDIは、次のようなCDIへのポータブルな拡張の開発を可能にするSPIを公開しています。

  • ビジネス・プロセス管理エンジンとの統合

  • Spring、Seam、GWT、Wicketなどサード・パーティのフレームワークとの統合

  • CDIプログラミング・モデルに基づいた新しいテクノロジ

CDIへのポータブルな拡張の開発を可能にするSPIは、javax.enterprise.inject.spiパッケージで提供されています。

CDIの拡張のコードは、CDIフレームワークによって送信されるイベントを処理できます。

詳細は、JSR 365: Contexts and Dependency Injection for the Java EE platformPortable extensionsを参照してください。

組込みアノテーション・リテラルの使用

CDI 2.0では、アノテーションのインスタンスの作成に使用できる新しい組込みアノテーション・リテラルが導入されています。

構文

次に、Literal静的ネスト・クラスを定義する新しい組込みアノテーションを示します。

表9-2 組込みアノテーション・リテラル

クラス パッケージ
Any javax.enterprise.inject
Default javax.enterprise.inject
New javax.enterprise.inject
Specialized javax.enterprise.inject
Veteod javax.enterprise.inject
Alternative javax.enterprise.inject
Typed javax.enterprise.inject
Nonbinding javax.enterprise.util
Initialized javax.enterprise.context
Destroyed javax.enterprise.context
RequestScoped javax.enterprise.context
SessionScoped javax.enterprise.context
ApplicationScoped javax.enterprise.context
Dependent javax.enterprise.context
ConversationScoped javax.enterprise.context

例9-31 組込みアノテーション・リテラル

Default defaultLiteral = new Default.Literal();

コンフィギュレータ・インタフェースの使用

CDI 2.0では、CDIオブジェクトを動的に定義または変更するために使用できる、新しいコンフィギュレータ・インタフェースがいくつか導入されました。

新しく導入されたコンフィギュレータ・インタフェースは次のとおりです。

  • AnnotatedTyeConfigurator
  • InjectionPointConfigurator
  • BeanAttributesConfigurator
  • BeanConfigurator
  • ObserverMethodConfigurator
  • ProducerConfigurator

詳細は、Java EE 8チュートリアルコンフィギュレータ・インタフェースの使用に関する項を参照してください。

CDIコンテナのブートストラップ

CDI 2.0では、Java SEのCDIコンテナをブートストラップするための標準APIが提供されます。SeContainerInitializer抽象クラスとその静的メソッドnewInstance()を使用して、CDIコンテナを明示的にブートストラップする必要があります。

ブートストラップされる前にAPI javax.enterprise.inject.se.SeContainerInitializerを使用してCDIコンテナを構成し、SeContainerInitializer.initialize()メソッドによってコンテナがブートストラップされ、SeContainerインスタンスが返されます。

詳細は、Java EE 8チュートリアルCDIコンテナの構成に関する項を参照してください。