web-dev-qa-db-ja.com

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

Core JavaServer Faces、3rd Ed。 を読み始めたところ、彼らはこれを言っています(私の強調):

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

どうして? any正当化を提供しません。 GlassFish 3で実行されているプロトタイプアプリケーションのすべてのBeanに@ManagedBeanを使用してきましたが、これに関する問題はほとんど気付きませんでした。 @ManagedBeanから@Namedへの移行は特に気にしませんが、知りたいのはなぜわざわざする必要があるです。

105
Matt Ball

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

62
Bozho

CDIを使用します。

JSF 2.3によると、@ManagedBean非推奨です。 spec issue 1417 もご覧ください。これは、@ManagedBeanよりも@Namedを選択する理由がなくなったことを意味します。これは、Mojarra 2.3.0ベータバージョンm06で最初に実装されました。

enter image description here


歴史

核となる違いは、 @ManagedBean はJSFフレームワークによって管理され、 @ManagedProperty を介してのみ別のJSF管理対象Beanで使用できることです。 @Named は、CDIフレームワークを介してアプリケーションサーバー(コンテナ)によって管理され、 @Inject@WebListener@WebFilter@WebServlet@Path@Statelessなどのあらゆる種類のコンテナ管理アーティファクトで利用可能など、さらにはJSF @ManagedBean。反対側から、@ManagedProperty@Namedまたは他のコンテナー管理アーティファクト内でnot動作しません。それは本当に@ManagedBean内でのみ動作します。

別の違いは、CDIが実際に要求スコープ/スレッドごとにターゲットスコープの現在のインスタンスに委任するプロキシを注入することです(EJBの注入方法など)。このメカニズムを使用すると、JSF @ManagedPropertyでは不可能な、より広いスコープのBeanに、より狭いスコープのBeanを注入できます。 JSFは、セッターを呼び出すことで物理インスタンスを直接「インジェクト」します(これは、セッターが必要な理由でもありますが、@Injectではnotが必要です)。

直接の欠点ではありませんが、他の方法もありますが、@ManagedBeanの範囲は単純に制限されています。もう1つの観点から、@Injectに「多すぎる」を公開したくない場合は、マネージドBeanを@ManagedBeanのままにしておくこともできます。 protectedpublicのようなものです。しかし、それは本当に重要ではありません。

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

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

168
BalusC

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

  • _@javax.faces.bean.ManagedBean_はJSR 314を参照し、JSF 2.0で導入されました。主な目標は、JSFページ内でBeanを使用するためのfaces-config.xmlファイルの構成を回避することでした。
  • @javax.annotation.ManagedBean(“myBean”)はJSR 316で定義されています。Java EE
  • @javax.inject.Named(“myBean”)は、上記とほぼ同じですが、CDIをアクティブにするにはweb/WEB-INFフォルダーにbeans.xmlファイルが必要です。
13
h2mch

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

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

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

2
AlanObject

CDIに移行する1つの理由:セッションスコープの共通リソース(ユーザープロファイルなど)をJSF管理BeanとRESTサービスの両方に_@Inject_ ') Jersey/JAX-RS)。

一方、_@ViewScoped_は、JSF _@ManagedBean_に固執する説得力のある理由です-特に重要なAJAXを使用する場合は特に。 CDIには、これに代わる標準的なものはありません。

CDI Beanの_@ViewScoped_のようなアノテーションをサポートしているようですが、私は個人的にそれをいじっていません。

http://seamframework.org/Seam3/FacesModule

0
wrschneider