[解決済み] Java EE 6 @javax.annotation.ManagedBean vs. @javax.inject.Named vs. @javax.faces.ManagedBean
質問
Java EE 6の仕様にちょっとした混乱があるように感じます。アノテーションのセットがいくつかあります。
私たちは
javax.ejb
のようなアノテーションがあります。
@Stateful
と
@Stateless
を使用してEJBを作成します。
また
@javax.annotation.ManagedBean
を使用してマネージドビーンを作成します。
にはアノテーションがあり
javax.enterprise.context
のように
@SessionScoped
そして
@RequestScoped
.
さらに
@ManagedBean
と
@SessionScoped
/
@RequestScoped
のアノテーションは
javax.faces.bean
パッケージで使用されます。
そして、さらに物事を複雑にするために、パッケージ
javax.inject
と
@Named
のアノテーションを使用します。
どなたか、これらが互いにどのように関連しているかを説明していただけませんか?
私はどこで
@EJB
,
@Inject
または
@ManagedPropery
で他のビーンを注入できますか?
どのように解決するのですか?
まず最初に、いくつかの点を確認させてください。
マネージドビーンの定義 一般にマネージドビーンとは、そのライフサイクル(構築、破壊など)がコンテナによって管理されるオブジェクトのことを指します。
Java eeでは、JSFコンテナ、EJBコンテナ、CDIコンテナ、サーブレットコンテナなど、オブジェクトのライフサイクルを管理する多くのコンテナを持っています。
これらのコンテナはすべて独立して動作し、アプリケーションサーバーの初期化で起動し、デプロイ時にjar、ejb-jar、war、earファイルを含むすべての成果物のクラスをスキャンし、それらに関するいくつかのメタデータを収集し保存して、実行時にクラスのオブジェクトが必要になると、それらのクラスのインスタンスを与え、仕事を終えた後はそれらを破壊します。
というわけで、私たちは
- JSFマネージドビーン
- CDIマネージドビーン
- EJBマネージドビーン
- そして、サーブレットでさえも、コンテナによってインスタンス化され、破棄されるため、マネージドビーンです。
ですから、Managed Beanという単語を見たら、その文脈や種類を聞くべきです(JSF、CDI、EJBなど)。
では、なぜこのようなコンテナがたくさんあるのかと思うかもしれません。AFAIKは、Java EEの人たちは依存性注入フレームワークを持ちたかったのですが、彼らは将来の要件を予測できなかったので、すべての要件を1つの仕様に集めることができず、EJB 1.0、2.0、3.0と現在3.1を作っています。
同時に(並行して)JSFもサポートする必要があることに気づき、JSFマネージドビーンズとJSFビーンズ用の別のコンテナを作り、それを成熟したDIコンテナと考えたが、まだ完全で成熟したコンテナではなかった。
その後、Gavin Kingと他の素晴らしい人たちがCDIを作りました。CDIは(Seam2、Guice、Springに触発されて)JSFとEJBの間のギャップを埋めるために作られ、pojoインジェクション、プロデューサーメソッド、インターセプター、デコレーター、統合SPI、非常に柔軟など、多くの役に立つものを含んでいます。しかし、後方互換性と政治的な理由で、Java EEはそれらを維持したいのです!
ここでは、それぞれのタイプの違いとユースケースを紹介します。
JSFマネージドビーン、CDIビーン、EJB
JSFは当初、独自のマネージドBeanと依存性注入メカニズムで開発されましたが、JSF 2.0ではアノテーションベースのBeanを含むよう強化されました。CDIがJava EE 6でリリースされたとき、それはそのプラットフォームのためのマネージドBeanフレームワークとみなされ、もちろん、EJBは10年をはるかに超えて存在しているため、それらをすべて追い越しました。
もちろん、問題は、どれを使うか、そしていつ使うかを知ることです。
最も単純な、JSFマネージドビーンズから始めましょう。
JSFマネージドビーン
要するに、もしあなたがJava EE 6のために開発し、CDIを使用しているならば、これらを使用しないでください。JSFマネージドビーンは、依存性注入とWebページのバッキングビーンを定義するための簡単なメカニズムを提供しますが、CDIビーンよりもはるかに強力ではありません。
これらは
@javax.faces.bean.ManagedBean
アノテーションを使用して定義することができ、オプションの名前パラメータを取ります。この名前は、JSFページからBeanを参照するために使用することができます。
で定義された異なるスコープの1つを使用して、ビーンにスコープを適用することができます。
javax.faces.bean
パッケージで定義された異なるスコープを使用してビーンに適用することが可能で、 リクエスト、セッション、アプリケーション、ビュー、カスタムスコープが含まれます。
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
JSFのBeanは、何らかの手動コーディングなしに他の種類のBeanと混在させることはできません。
CDIビーン
CDI は Java EE 6 の一部としてリリースされた Bean 管理および依存性注入フレームワークであり、完全で包括的なマネージド Bean 機能を含んでいます。CDIビーンズは、単純なJSF管理ビーンズよりもはるかに高度で柔軟です。インターセプター、会話スコープ、イベント、タイプセーフインジェクション、デコレーター、ステレオタイプ、プロデューサーメソッドを利用することができます。
CDIビーンを配備するには、クラスパスのMETA-INFフォルダーにbeans.xmlと呼ばれるファイルを配置する必要があります。一度これを行うと、パッケージ内のすべてのビーンがCDIビーンになります。CDI には多くの機能があり、ここで取り上げるには多すぎますが、JSF のような機能のクイックリファレンスとして、CDI ビーンのスコープは
javax.enterprise.context
パッケージで定義されたスコープ (すなわち、リクエスト、会話、セッション、およびアプリケーションのスコープ) のいずれかを使用して CDI Bean のスコープを定義します。JSF ページから CDI Bean を使用したい場合、CDI Bean に名前を付けるには、CDI Bean を使用するための
javax.inject.Named
アノテーションを使用します。Beanを他のBeanに注入するには、そのフィールドにアノテーションを付けます。
javax.inject.Inject
アノテーションを使用します。
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
上で定義したような自動注入は、注入したい特定のクラスにマッチさせるのに役立つ修飾子を使用することで制御することができます。複数の支払いタイプがある場合、非同期かどうかの修飾子を追加することができます。また
@Named
アノテーションを使用することもできますが、これはELでBeanを公開するために用意されているものなので、使用すべきではありません。
CDIはプロキシの使用により、不一致のスコープを持つBeanの注入を処理します。このため、リクエストスコープのBeanをセッションスコープのBeanに注入することができ、各リクエストにおいて、プロキシはリクエストスコープのBeanのライブインスタンスに再接続するため、参照はまだ有効でしょう。
CDIはまた、インターセプター、イベント、新しい会話スコープ、および他の多くの機能をサポートしており、JSFマネージドビーンよりもはるかに優れた選択肢となっています。
EJB
EJBはCDIビーンより先に開発され、ある意味ではCDIビーンに似ていますが、他の意味では非常に異なっています。主に、CDIビーンズとEJBの違いは、EJBは:
- トランザクション
- リモートまたはローカル
- ステートフル Bean を無効化し、リソースを解放することができます。
- タイマーを使用することができます。
- 非同期が可能
EJBにはステートレス(stateless)とステートフル(stateful)という2つのタイプがあります。ステートレスEJBは、2つのWebリクエストの間で状態を保持しない、スレッドセーフな単一使用Beanと考えることができます。ステートフルEJBは状態を保持し、作成され、廃棄されるまでの間、必要なだけ存在することができます。
EJBを定義するのは簡単です。
javax.ejb.Stateless
または
javax.ejb.Stateful
のアノテーションをクラスに追加します。
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
ステートレスBeanは従属スコープを持たなければなりませんが、ステートフルセッションBeanは任意のスコープを持つことができます。デフォルトではそれらはトランザクションですが、トランザクション属性アノテーションを使用することができます。
EJBとCDI Beanは機能の面で大きく異なりますが、CDI BeanはEJBに注入でき、EJBはCDI Beanに注入できるので、統合するためのコードを書くことは非常に似ています。一方を他方に注入する際に、区別する必要はありません。ここでも、異なるスコープはプロキシを使用することによってCDIによって処理されます。この例外として、CDI はリモート EJB の注入をサポートしていませんが、 それはそれのための簡単なプロデューサーメソッドを書くことによって 実装することができます。
は
javax.inject.Named
アノテーションと同様に Qualifiers を EJB で使用して、注入ポイントにマッチさせることができます。
いつどのビーンを使うか
どのビーンをいつ使うか、どうやって知るのでしょうか?簡単です。
サーブレットコンテナで作業していて、TomcatでCDIを動作させることを試したくない場合(そのためのいくつかのMavenアーキタイプがあるので言い訳はできませんが)、JSFマネージドBeanは決して使用しないでください。
一般的には、トランザクション機能などEJBで利用できる高度な機能が必要でない限り、CDI Beanを使用すべきです。CDI Beanをトランザクションにするために独自のインターセプターを書くことはできますが、今のところ、CDIがトランザクションCDI Beanを手に入れるまで、EJBを使う方がシンプルです。サーブレットコンテナから抜け出せず、CDIを使用している場合、手書きのトランザクションか、独自のトランザクションインターセプターが、EJBなしの唯一の選択肢となります。
を使う必要がある場合
@ViewScoped
を使う必要がある場合、CDIでは
-
使用
縫い目
または
マイフェイスCODI
モジュールのいずれかをクラスパスに追加して
@ViewScoped
はCDIで動作します。MyFaces CODIは@ViewScopedをさらに強固にサポートしています。 -
は、MyFaces CODIの
@ViewAccessScoped
は、Apache による CDI の上に書かれた拡張機能であり、単に ダウンロード をダウンロードし@ViewAccessScoped
アノテーションの代わりに@ViewScoped
. -
CDIを使用する
@ConversationScoped
を使い、ロングランさせる。参照 をご覧ください。 . - 使用方法 オムニフェーズ ViewScopedアノテーション
いくつかの部分は ここから .
関連
-
JAVA_HOME環境変数が正しく定義されていない問題を解決する
-
XXX型を囲むインスタンスがJavaでアクセスできない
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Eclipseは、ポップアップA Java Exception has occurred.を実行し、エラーException in threadの解決策を報告します。
-
undefined[sonar] sonar:デフォルトのスキャンルール
-
Springの設定でxsdファイルのバージョン番号を設定しない方が良い理由
-
Javaがテキストファイルを読み込む
-
Java:未解決コンパイル問題の解決方法
-
Java の double データ型における 0.0 と -0.0 の問題
-
アクセス制限の解決方法: ---- in Java
-
IDEAError:javaの依存性エラー。Annotation processing is not supported for module cycles...(アノテーション処理はモジュールサイクルではサポートされていません。
-
[解決済み] Backing Bean (@ManagedBean) か CDI Beans (@Named) か?
-
[解決済み] CDIとEJBはどう違うのか、相互作用は?