バッキング Bean (@ManagedBean) または CDI Bean (@Named)?
質問
まだ読み始めたばかりです Core JavaServer Faces、第 3 版 そして彼らはこう言います(私の言葉を強調):
JSFページで使用できる豆用の2つの別々のメカニズム、CDI豆とJSFマネージドビーンズがあることは歴史的な事故です。 CDI豆を使用することをお勧めします アプリケーションがTomcatなどのプレーンサーブレットランナーで動作する必要がない限り。
なぜ?彼らは提供しません どれでも 正当化。私は使ってきました @ManagedBean
GlassFish 3 で実行されているプロトタイプ アプリケーションのすべての Bean に対して、これに関する問題は特に気付きませんでした。からの移行は特に気にしません @ManagedBean
に @Named
, 、でも知りたい なぜわざわざ私がしなければならないのか.
解決
CDIはJavaee全体の依存噴射を可能にするため、CDIはプレーンJSFよりも好まれます。ポジョを注入して、それらを管理することもできます。 JSFを使用すると、CDIでできるもののサブセットのみを注入できます。
他のヒント
CDIを使用します。
JSF 2.3 によると、 @ManagedBean
は 廃止された. 。こちらも参照 仕様問題 1417. 。つまり、もう選ぶ理由がないということです @ManagedBean
以上 @Named
. 。これは Mojarra 2.3.0 ベータ版 m06 で初めて実装されました。
歴史
核心的な違いは、 @ManagedBean
JSF フレームワークによって管理され、経由でのみ使用できます。 @ManagedProperty
別の JSF 管理 Bean で使用できます。 @Named
CDI フレームワークを介してアプリケーション サーバー (コンテナ) によって管理され、 @Inject
あらゆる種類のコンテナ管理アーティファクトで利用可能 @WebListener
, @WebFilter
, @WebServlet
, @Path
, @Stateless
, 、など、さらには JSF @ManagedBean
. 。反対側からは、 @ManagedProperty
する ない 中で働く @Named
またはその他のコンテナー管理アーティファクト。本当に内部でのみ機能します @ManagedBean
.
もう 1 つの違いは、CDI がリクエスト/スレッドごとにターゲット スコープ内の現在のインスタンスに委任するプロキシを実際に挿入することです (EJB の挿入方法と同様)。このメカニズムにより、JSF では不可能な、より狭いスコープの Bean をより広いスコープの Bean に注入できます。 @ManagedProperty
. 。JSF は、セッターを呼び出すことによって物理インスタンスを直接ここに「挿入」します (これがまさにセッターが必要な理由でもありますが、それは ない 必須 @Inject
).
直接的なデメリットではありませんが、他の方法もあります。 @ManagedBean
単に限られているだけです。別の観点から見ると、「あまりにも多くのこと」を公開したくない場合は、 @Inject
, 、マネージド Bean をそのまま保持することもできます @ManagedBean
. 。まるで protected
対 public
. 。しかし、それは実際には重要ではありません。
少なくとも、JSF 2.0/2.1 では、CDI によって JSF バッキング Bean を管理することの主な欠点は、CDI に相当するものが存在しないことです。 @ViewScoped
. 。の @ConversationScoped
かなり近づいていますが、それでも手動で開始および停止する必要があり、醜いコードが追加されます。 cid
リクエストパラメータを結果 URL に渡します。MyFaces CODI は、JSF を完全に透過的にブリッジすることで作業を容易にします。 javax.faces.bean.ViewScoped
CDI に送信すれば、次のようにすることができます @Named @ViewScoped
, ただし、それは醜いことを追加します windowId
リクエスト パラメータを結果 URL に送信します。プレーンなバニラのページ間ナビゲーションでも同様です。 オムニフェイス 真の CDI ですべてを解決します @ViewScoped
これにより、Bean のスコープが任意のリクエスト パラメータではなく JSF ビュー ステートに実際に結び付けられます。
JSF 2.2 (この質問と回答の 3 年後にリリース) は、完全に CDI と互換性のある新しい機能を提供します。 @ViewScoped
すぐに使える注釈 javax.faces.view.ViewScoped
. 。JSF 2.2 には CDI のみの機能も付属しています @FlowScoped
を持たないもの @ManagedBean
これにより、JSF ユーザーが CDI に向かうようになります。期待されるのは、 @ManagedBean
Java EE 8 に従って、フレンドは非推奨になります。現在も使用している場合 @ManagedBean
, したがって、将来のアップグレード パスに備えて CDI に切り替えることを強くお勧めします。CDI は、WildFly、TomEE、GlassFish などの Java EE Web プロファイル互換コンテナですぐに利用できます。Tomcat の場合は、JSF の場合とまったく同じように、個別にインストールする必要があります。こちらも参照 Tomcat に CDI をインストールするにはどうすればよいですか?
Java EE 6とCDIを使用する
@javax.faces.bean.ManagedBean
JSR 314を参照し、JSF 2.0で導入されました。主な目標は、faces-config.xmlファイルの構成を回避して、JSFページ内のBeanを使用することでした。@javax.annotation.ManagedBean(“myBean”)
JSR 316で定義されています。JavaEEの他の場所で使用するJSFマネージドビーンズを一般化します@javax.inject.Named(“myBean”)
CDIをアクティブにするためにWeb/Web-INFフォルダーにBeans.xmlファイルが必要であることを除いて、上記のものとほぼ同じです。
私はGlassfish 3.0.1でCDIを使用していましたが、それを機能させるには、Seam 3フレームワーク(溶接)をインポートする必要がありました。それはかなりうまくいきました。
Glassfish 3.1では、CDIが動作を停止し、縫い目溶接が動作を停止しました。私はAを開けました これに関するバグ しかし、まだ修正されたのを見ていません。すべてのコードをjavax.facesを使用して変換する必要がありました。
CDIを使用する必要があることに同意しますが、私がまだ解決していない問題の1つは、@ViewScoped Annotationをどうするかです。私はそれに依存する多くのコードを持っています。 @ManagedBeanを使用していない場合、@ViewScopedが機能するかどうかは明らかではありません。誰かがこれを明確にすることができれば、私はそれを感謝します。
CDIに移行する1つの正当な理由:共通のセッションスコープリソース(たとえば、ユーザープロファイル)を持つことができます @Inject
'JSFマネージドビーンズとレストサービスの両方に編集されました(すなわち、ジャージー/JAX-RS)。
一方で、 @ViewScoped
JSFに固執する説得力のある理由です @ManagedBean
- 特に重要なAJAXの場合は何でも。 CDIにはこれに関する標準的な代替品はありません。
aのサポートがあるかもしれません @ViewScoped
- cdi豆の注釈のように、しかし私はそれを個人的に演奏していません。