バッキングBean(@ManagedBean)またはCDI Bean(@Named)?


109

Core JavaServer Faces、第3版を読み始めたところです。そして彼らはこれを言う(私の強調):

JSFページで使用できるBeanには、CDI BeanとJSF管理Beanの2つの別個のメカニズムがあるのは歴史的な事故です。アプリケーションがTomcatなどのプレーンサーブレットランナーで動作する必要がない限り、CDI Beanを使用することをお勧めします

どうして?彼らは提供していない任意の正当性を。私は@ManagedBeanGlassFish 3で実行されているプロトタイプアプリケーションのすべてのBean を使用してきましたが、これに関する問題に気づきませんでした。から@ManagedBeanへの移行は特に問題ではありませんが@Namedなぜ煩わしいのかを知りたいのです。



4
@Bozho:その質問はかなり似ていますが、Pascalの回答を数回読んだ後も、CDIがはるかに優れている理由がわかりません。CDIについては知りませんが、「より良い」ので、CDIを学ぶことができてうれしいです。なぜそれが良いのですか?
Matt Ball

「アプリケーションがTomcatなどのプレーンサーブレットランナーで動作する必要がない限り」私はtomcatのみを使用しており、CDIを強くお勧めします。Tomcatは問題なくサポートできます
KarlKildén'17年

1
@KarlKildén "プレーンサーブレットランナー"は、CDI非対応のサーブレットコンテナを指します。執筆時点では、Tomcatはかなりの魔法を除いてCDIをサポートしていませんでした。
–ThorbjørnRavn Andersen 2012

回答:


64

CDIではJavaEE全体の依存性注入が可能であるため、プレーンなJSFよりもCDIが推奨されます。POJOを挿入して管理することもできます。JSFでは、CDIでできることのサブセットのみを注入できます。


したがって、基本的に、CDIを使用してほぼすべてのクラスのインスタンス(「適切なもの」がある場合、それは何も引数なしのコンストラクターですか?@ManagedBeanを注入できますが、プレーンで注入したい場合は使用する必要がありますJSF?
Matt Ball

3
@MattBall Matt数年後、この移行についてコメントできますか?
Koray Tugay 2013年

5
@KorayTugay 2011年6月以来、このコードには触れていませんが、CDIに切り替えていて、問題なく動作しました。あなたがそれらを持っているなら、私は私の記憶の中で最高の特定の質問に答えさせていただきます。
マットボール

170

CDIを使用します。

JSF 2.3に従い、@ManagedBean非推奨です仕様の問題1417も参照してください。もう選択する理由がないことを、この手段@ManagedBeanを超えます@Named。これはMojarra 2.3.0ベータバージョンm06で最初に実装されました。

ここに画像の説明を入力してください


歴史

中心的な違いは、@ManagedBeanJSFフレームワークによって管理され@ManagedProperty、別のJSF管理Beanでのみ使用できることです。@NamedCDI・フレームワークを介してアプリケーションサーバ(コンテナ)で管理を介してである@Injectようなコンテナ管理アーチファクトの任意の種類の利用可能な@WebListener@WebFilter@WebServlet@Path@Stateless、などともJSF @ManagedBean。反対側から見ると、またはその他のコンテナ管理のアーティファクト内で@ManagedPropertyは機能しませ@Named。内部でのみ機能します@ManagedBean

もう1つの違いは、CDIは実際に、ターゲットスコープの現在のインスタンスに委任するプロキシを、リクエスト/スレッドごとに(EJBの注入方法などのように)注入することです。このメカニズムにより、より狭いスコープのBeanをより広いスコープのBeanに挿入できますが、これはJSFでは不可能@ManagedPropertyです。JSFは、ここで、setterを呼び出すことによって物理インスタンスを直接「注入」します(それが、setterが必要であるのとまったく同じ理由ですが、では必要ありません@Inject)。

直接の欠点ではありませんが、他の方法があります—の範囲@ManagedBeanは単に制限されています。別の見方をすると、について「あまりにも」公開したくない場合は@Inject、マネージドBeanだけを保持することもできます@ManagedBeanprotected対のようなものpublicです。しかし、それは実際には重要ではありません。

少なくとも、JSF 2.0 / 2.1では、JSFバッキングBeanをCDIで管理することの主な欠点は、に相当するCDIがないことです@ViewScoped@ConversationScoped近づくが、それでも手動起動と停止要求し、それが醜い追加しcid、結果のURLへのリクエストパラメータを。MyFaces CODIは、JSFを完全に透過的javax.faces.bean.ViewScopedにCDIにブリッジして簡単にできるようにします@Named @ViewScoped。ただし、windowId単純なページ間のナビゲーションでも、結果のURLに醜い要求パラメーターを追加します。OmniFaces@ViewScopedは、Beanのスコープを任意のリクエストパラメータではなくJSFビューステートに実際に結び付ける真のCDI でこれをすべて解決します。

JSF 2.2(この質問/回答から3年後にリリースされます)は、の@ViewScopedフレーバーで、完全なCDI互換の新しいアノテーションを提供しますjavax.faces.view.ViewScoped。JSF 2.2に@FlowScopedは、@ManagedBean同等のものがないCDIのみが付属しているため、JSFユーザーはCDIに向かっています。@ManagedBeanJava EE 8に従って、友人は非推奨になると予想されます。現在をまだ使用している場合は@ManagedBean、将来のアップグレードパスに備えてCDIに切り替えることを強くお勧めします。CDIは、WildFly、TomEE、GlassFishなどのJava EE Webプロファイル互換コンテナーですぐに利用できます。Tomcatの場合は、JSFの場合とまったく同じように、個別にインストールする必要があります。TomcatにCDIをインストールする方法も参照してください。


4
を作成しbeans.xml@ManagedBeanバッキングBeanを@Namedに変換@ManagedPropertyし、に変換しました@Inject。すべてが世界に順調です。ただし、@EJB注釈をに変更すると@Injectorg.jboss.weld.exceptions.DeploymentExceptionメッセージ()でデプロイメントが失敗しますWELD-001408 Injection point has unsatisfied dependencies@InjectインターフェースなしのEJBを@NamedBean に挿入するために実際に使用する必要があり@EJBますか、それともそのまま使用する必要がありますか?EJBは、CDI Beanを含むWARと同じEARのEJB JARにパッケージ化されています。
Matt Ball

うまくいくはずです。現在のWeldバージョンでもこの問題に直面していますか?
BalusC 2013

悲しいかな、私は言うことができませんでした。この質問は2人の雇用主からのもので、2年以上前です。Bozhoの答えに関する私の古いコメントに基づいて、私はCDI /に切り替えたに違いありません@Named
マットボール

「MyFaces CODIは、JSFのjavax.faces.bean.ViewScopedを完全に透過的にCDIにブリッジして簡単にできるようにします@Named @ViewScoped。ただし、単純なページ間ナビゲーションでも、結果のURLに醜いwindowIdリクエストパラメータを追加します。」 DeltaSpikeでは、これは当てはまらないことに注意してください。ウィンドウスコープが必要ない場合は、dsIdとwindowIdの両方のURLパラメーターを無効にできます。
JanM 2013年

1
@Jan:そして一方では、OmniFacesもJSFを持っている2.2のようには@ViewScopedJSF 2.0 / 2.1用:showcase.omnifaces.org/cdi/ViewScoped
BalusC

16

Java EE 6とCDIでは、マネージドBeanに異なるオプションがあります

  • @javax.faces.bean.ManagedBeanJSR 314を参照し、JSF 2.0で導入されました。主な目標は、faces-config.xmlファイルの構成を回避して、JSFページ内でBeanを使用することでした。
  • @javax.annotation.ManagedBean(“myBean”) JSR 316によって定義されています。これは、Java EEの他の場所で使用するためにJSF管理対象Beanを一般化します
  • @javax.inject.Named(“myBean”) CDIをアクティブ化するには、web / WEB-INFフォルダーにbeans.xmlファイルが必要であることを除いて、上記のものとほとんど同じです。

1
最初の2つの違いは何ですか?
マットボール

最初のアノテーションの目的は、JSFで使用するためにfaces-config.xmlのBean構成を置き換えることです。2つ目は、コンセプトを「java ee 6コンテナ」にコピーします。@PostConstructアノテーションや@PreDestroyアノテーションなど、より多くの関数がありますが、JSFページ(式言語を使用)からもアクセスできます。
h2mch 2010

1
なぜbeans.xmlファイルが必要なのですか?これは今日でも本当ですか?
Thufir 2014年

2
いいえ、JavaEE7では、beans.xmlは必要ありません。docs.oracle.com/javaee/7/tutorial/doc/cdi-adv001.htmを
h2mch

1
:JavaEE7を使用すると、beans.xmlの必要はありません docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm(正しいリンク) blogs.oracle.com/theaquarium/entry/... Javaで(デフォルトCDI有効化をEE 7)
M. Atif Riaz 2016年

2

GlassFish 3.0.1でCDIを使用していましたが、それを機能させるにはSeam 3フレームワーク(Weld)をインポートする必要がありました。それはかなりうまくいきました。

GlassFish 3.1では、CDIが機能しなくなり、Seam Weldがそれを使用しなくなりました。私はこれに関するバグをオープンしましたが、まだ修正されているのを見ていません。すべてのコードをjavax.faces。*アノテーションを使用するように変換する必要がありましたが、機能するようになったらCDIに戻る予定です。

CDIを使用する必要があることに同意しますが、まだ解決されていない問題の1つは、@ ViewScopedアノテーションをどうするかです。それに依存するコードがたくさんあります。@ManagedBeanを使用していない場合に@ViewScopedが機能するかどうかは明確ではありません。誰かがこれを明確にできるならば、私はそれを感謝します。


-1

CDIに移行する理由の1つは、@InjectJSFマネージドBeanとRESTサービス(Jersey / JAX-RSなど)の両方に共通のセッションスコープのリソース(ユーザープロファイルなど)を設定できることです。

一方で、@ViewScopedJSFに固執するのはやむを得ない理由@ManagedBeanです。特に、重要なAJAXがあるものには特にそうです。CDIには、これに代わる標準はありません。

@ViewScopedCDI Beanの-likeアノテーションをある程度サポートしているようですが、私は個人的には使用していません。

http://seamframework.org/Seam3/FacesModule

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.