正しいBeanスコープの選択方法は?


381

次のような異なるBeanスコープがあることに気づきました。

@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped

それぞれの目的は何ですか?Beanに適切なスコープを選択するにはどうすればよいですか?


回答:


485

前書き

Beanのスコープ(存続期間)を表します。これは、基本的なサーブレットWebアプリケーションの「裏側」での動作に慣れていると、理解しやすくなります。サーブレットはどのように機能しますか?インスタンス化、セッション、シェア変数、マルチスレッド


@Request/View/Flow/Session/ApplicationScoped

@RequestScopedBeanは、長い単一のHTTPリクエスト・レスポンス・サイクルとして(なお、単一のHTTPリクエストとしてAjaxリクエストカウントすぎ)と暮らしています。@ViewScopedあなたはコールアクションメソッドが返すポストバックによって同じJSFビューと対話しているようBeanは限り生きてnull/ void任意のナビゲーション/リダイレクトなし。@FlowScoped限り、あなたは、フロー設定ファイルに登録されたビューの指定されたコレクションをナビゲートしているとしてBeanが命。@SessionScopedBeanは老舗HTTPセッションなどとして住んでいます。@ApplicationScoped豆は、長いWebアプリケーションの実行などとして住んでいます。CDI @Modelは基本的にのステレオタイプであるため@Named @RequestScoped、同じルールが適用されることに注意してください。

どのスコープを選択するかは、Beanが保持および表現するデータ(状態)にのみ依存します。使用@RequestScopedシンプルかつ非AJAXフォーム/プレゼンテーションに。使用@ViewScoped豊富なAjax対応の動的ビュー(ajaxbasedバリデーション、レンダリング、ダイアログなど)のために。使用する@FlowScoped「ウィザード」(「アンケート」)複数のページ上の入力データの広がりを収集するパターンのために。@SessionScopedログインしたユーザーやユーザー設定(言語など)などのクライアント固有のデータに使用します。@ApplicationScoped誰もが同じドロップダウンリストや、インスタンス変数を持たずメソッドのみを持つマネージドBeanなど、アプリケーション全体のデータ/定数に使用します。

@ApplicationScopedBeanをセッション/ビュー/リクエストスコープのデータに悪用すると、すべてのユーザー間で共有されるため、他の誰もがお互いのデータを見ることができますが、これは明らかに間違っています。@SessionScopedビュー/リクエストスコープのデータにBeanを悪用すると、単一のブラウザーセッションですべてのタブ/ウィンドウ間で共有されるため、エンドユーザーは、タブを切り替えた後にすべてのビューを操作するときに不便を感じる可能性があり、ユーザーエクスペリエンスに悪影響を及ぼします。@RequestScopedビュースコープデータにBeanを悪用すると、ビュースコープデータがすべての(ajax)ポストバックでデフォルトに再初期化され、機能しないフォームが発生する可能性があります(ここのポイント4と5も参照)。悪用@ViewScopedリクエスト、セッションまたはアプリケーションスコープのデータのための豆を、そしてAを乱用@SessionScoped アプリケーションスコープのデータのBeanはクライアントに影響を与えませんが、サーバーのメモリを不必要に占有し、非効率的です。

実際にメモリフットプリントが低く、完全にステートレスにしたい場合を除き、パフォーマンスへの影響に基づいてスコープを選択しないでください。@RequestScopedクライアントの状態を維持するには、Beanとフィドルのみをリクエストパラメータとともに使用する必要があります。また、スコープが異なるデータを持つ単一のJSFページがある場合、データのスコープと一致するスコープ内の個別のバッキングBeanにそれらを配置することは完全に有効です。@ManagedPropertyJSF管理Beanの@Inject場合、またはCDI管理Beanの場合、Beanは互いにアクセスするだけです。

以下も参照してください。


@CustomScoped/NoneScoped/Dependent

質問では触れていませんが、(レガシー)JSFは@CustomScopedおよびもサポートして@NoneScopedいます。@CustomScopedカスタム参照する必要がありますMap<K, Bean>オーバーライドしているいくつかのより広い範囲での実装Map#put()および/またはMap#get()豆の作成をよりきめの細かい制御を持っている、および/または破壊するためには。

JSF @NoneScopedとCDIは、@Dependent基本的に、Beanの単一のEL評価である限り有効です。Beanプロパティを参照する2つの入力フィールドとBeanアクションを参照するコマンドボタンがあるログインフォームを想像してください。したがって、合計3つのEL式を使用すると、事実上3つのインスタンスが作成されます。1つはユーザー名が設定され、もう1つはパスワードが設定され、もう1つはアクションが呼び出されます。通常、このスコープは、注入先のBeanと同じ長さのBeanでのみ使用します。したがって、@NoneScopedまた@Dependentはがに注入された@SessionScoped場合、@SessionScopedBeanと同じ長さで存続します。

以下も参照してください。


フラッシュスコープ

最後に、JSFはflashスコープもサポートしています。これは、セッションスコープのデータエントリに関連付けられた短いリビングCookieによってサポートされます。リダイレクトの前に、セッションスコープのデータエントリに一意に関連付けられている値を使用して、HTTP応答にCookieが設定されます。リダイレクト後、フラッシュスコープCookieの存在が確認され、Cookieに関連付けられたデータエントリがセッションスコープから削除され、リダイレクトされたリクエストのリクエストスコープに配置されます。最後に、CookieがHTTP応答から削除されます。このようにして、リダイレクトされた要求は、最初の要求で準備された要求スコープデータにアクセスできます。

これは実際にはマネージドBeanスコープとしては使用できません@FlashScoped。つまり、などはありません。flashスコープはExternalContext#getFlash()、管理対象Beanと#{flash}ELを介したマップとしてのみ使用できます。

以下も参照してください。


4
ここでは、「JSFでビュースコープBeanがいつどのように破棄されるのか」という質問への回答への参照が関連していると思います。
Lii

3
@Cold:これは古いCDIスコープであり、JSF 2.2では置き換えられています@FlowScoped(手動で開始/停止する必要はありません)。
BalusC 2016年

1
さらにDeltaSpikeにはさらにViewAccesscopedWindowScoped
Kukeltje

@ BalusC、ViewScopedMyFaces 2.2のBeanに問題があると思います。現在、ここにViewScoped投稿したBeanとAjaxの問題に直面しています。MyFaces JIRAでは、このトピックに関するディスカッションもあります。
タパスボーズ

CDIは4つの組み込みスコープを定義しています。 @RequestScoped @SessionScoped @ApplicationScoped @ConversationScoped なぜ、記述したスコープが異なるのですか?
Hosein Aqajani 19/07/24

122

JSF 2.3以降、パッケージjavax.faces.beanpackageで定義されたすべてのBeanスコープは、スコープをCDIに合わせるために非推奨になりました。さらに、Beanが@ManagedBeanアノテーションを使用している場合にのみ適用されます。2.3未満のJSFバージョンを使用している場合は、最後の従来の回答を参照してください。


JSF 2.3以降、JSFバッキングBeanで使用できるスコープは次のとおりです。

1@javax.enterprise.context.ApplicationScoped .:アプリケーションスコープは、Webアプリケーションの全期間中持続します。そのスコープは、すべてのリクエストとすべてのセッションで共有されます。これは、アプリケーション全体のデータがある場合に役立ちます。

2@javax.enterprise.context.SessionScoped .:セッションスコープは、セッションが確立されてから終了するまで存続します。セッションコンテキストは、同じHTTPセッションで発生するすべての要求間で共有されます。これは、特定のセッションの特定のクライアントのデータを保存しない場合に役立ちます。

3@javax.enterprise.context.ConversationScoped .:会話スコープは、Beanが生きている間、ログとして存続します。スコープは2つのメソッドを提供します:Conversation.begin()Conversation.end()。これらのメソッドは、Beanの寿命を開始または終了するために、明示的に呼び出す必要があります。

4.:@javax.enterprise.context.RequestScopedリクエストスコープは短命です。これは、HTTP要求が送信されたときに始まり、応答がクライアントに送り返された後に終了します。マネージドBeanをリクエストスコープに配置すると、リクエストごとに新しいインスタンスが作成されます。セッションスコープのストレージのコストが心配な場合は、リクエストスコープを検討する価値があります。

5@javax.faces.flow.FlowScoped .:フロースコープは、フローが存続する限り存続します。フローは、作業の単位を定義する一連のページ(またはビュー)として定義できます。スコープされたフローは、ユーザーがフロー内を移動する限りアクティブです。

6@javax.faces.view.ViewScoped .:同じJSFページが再表示されている間、ビュースコープのBeanが存続します。ユーザーが別のページに移動するとすぐに、Beanはスコープ外になります。


次のレガシー回答は、2.3以前のJSFバージョンを適用します

JSF 2.x以降、4つのBeanスコープがあります。

  • @SessionScoped
  • @RequestScoped
  • @ApplicationScoped
  • @ViewScoped

セッションスコープ:セッションスコープ は、セッションが確立されてから終了するまで存続します。WebアプリケーションがHttpSessionオブジェクトのinvalidateメソッドを呼び出すか、タイムアウトになると、セッションが終了します。

RequestScope: リクエストスコープは短命です。これは、HTTP要求が送信されたときに始まり、応答がクライアントに送り返された後に終了します。マネージドBeanをリクエストスコープに配置すると、リクエストごとに新しいインスタンスが作成されます。セッションスコープのストレージのコストが心配な場合は、リクエストスコープを検討する価値があります。

ApplicationScope: アプリケーションスコープは、Webアプリケーションの期間全体にわたって持続します。そのスコープは、すべてのリクエストとすべてのセッションで共有されます。Webアプリケーションのすべてのインスタンス間で単一のBeanを共有する必要がある場合は、管理対象Beanをアプリケーションスコープに配置します。Beanは、アプリケーションのユーザーが最初に要求したときに作成され、Webアプリケーションがアプリケーションサーバーから削除されるまで存続します。

ViewScope: ビューのスコープはJSF 2.0で追加されました。ビュー範囲内のBeanは、同じJSFページが再表示されている間も存続します。(JSF仕様では、JSFページのビューという用語を使用しています。)ユーザーが別のページに移動するとすぐに、Beanはスコープ外になります。

要件に基づいてスコープを選択します。

出典: Core Java Server Faces 3rd Edition by David Geary&Cay Horstmann [ページ番号。51〜54] ここに画像の説明を入力してください


「HttpSessionオブジェクトのinvalidateメソッド」とはどういう意味invalidate()ですか?メソッド、または無効なメソッドですか?
Alexander Pozdneev、2015

1
少し古く、おそらく返答が遅いかもしれませんが、明確にするためFacesContext.getCurrentInstance().getExternalContext().invalidateSession();に、「ログアウトBean」で呼び出されることを意味します。
Roland

1
それはレガシーな答えになりました、現時点では8つのスコープがあります
Ewoks

@KishorPrakash:しばらく前から6か月前。;-)
Kukeltje

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