以下のようなさまざまなBeanスコープがあることに気付きました。
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
それぞれの目的は何ですか?自分のBeanに適切なスコープを選択する方法
Beanのスコープ(有効期間)を表します。これは、基本的なサーブレットWebアプリケーションの「隠れた」動作に精通している場合に理解しやすくなります。 サーブレットはどのように動作しますか?インスタンス化、セッション、共有変数、マルチスレッド 。
@Request/View/Flow/Session/ApplicationScoped
@RequestScoped
Beanは、単一のHTTPリクエスト-レスポンスサイクルの間存続します(Ajaxリクエストも単一のHTTPリクエストとしてカウントされることに注意してください)。 @ViewScoped
Beanは、ナビゲーション/リダイレクトなしでnull
/void
を返すアクションメソッドを呼び出すポストバックにより、同じJSFビューと対話している限り有効です。 @FlowScoped
Beanは、フロー構成ファイルに登録されたビューの指定されたコレクションをナビゲートしている限り有効です。 @SessionScoped
Beanは、確立されたHTTPセッションが存続する限り有効です。 @ApplicationScoped
Beanは、Webアプリケーションが実行されている限り有効です。 CDI @Model
は基本的に@Named @RequestScoped
の ステレオタイプ であるため、同じ規則が適用されることに注意してください。
選択するスコープは、Beanが保持および表すデータ(状態)のみに依存します。 @RequestScoped
を使用して、シンプルで非ajaxのフォーム/プレゼンテーションを作成します。リッチAjax対応の動的ビュー(ajaxベースの検証、レンダリング、ダイアログなど)には@ViewScoped
を使用します。複数ページにまたがる入力データを収集する「ウィザード」(「アンケート」)パターンに@FlowScoped
を使用します。ログインしたユーザーやユーザー設定(言語など)などのクライアント固有のデータには、@SessionScoped
を使用します。 @ApplicationScoped
は、全員に共通のドロップダウンリストや、インスタンス変数を持たず、メソッドのみを持つマネージドBeanなど、アプリケーション全体のデータ/定数に使用します。
セッション/ビュー/リクエストスコープデータの@ApplicationScoped
Beanを乱用すると、すべてのユーザー間で共有されるため、他の誰でも互いのデータを見ることができますが、これはまったく間違っています。ビュー/リクエストスコープデータの@SessionScoped
Beanを乱用すると、単一のブラウザーセッションですべてのタブ/ウィンドウ間で共有されるため、エンドユーザーは、タブを切り替えた後にすべてのビューを操作するときに不便を感じることがあります。ビュースコープデータの@RequestScoped
Beanを乱用すると、ビュースコープデータがすべての単一(ajax)ポストバックでデフォルトに再初期化され、動作しないフォームが発生する可能性があります( ポイント4と5も参照 )。 @ViewScoped
Beanを要求、セッション、またはアプリケーションスコープのデータに乱用し、@SessionScoped
Beanをアプリケーションスコープのデータに乱用してもクライアントには影響しませんが、サーバーメモリを不必要に占有し、効率が悪くなります。
reallyのメモリフットプリントが小さく、完全にステートレスになりたくない場合を除き、パフォーマンスへの影響に基づいてスコープを選択しないでください。クライアントの状態を維持するには、@RequestScoped
Beanのみを使用し、リクエストパラメータをいじる必要があります。また、スコープが異なるデータを持つ単一のJSFページがある場合、それらをデータのスコープに一致するスコープ内の個別のバッキングBeanに入れることは完全に有効です。 Beanは、JSF管理Beanの場合は@ManagedProperty
、CDI管理Beanの場合は@Inject
を介して相互にアクセスできます。
@CustomScoped/NoneScoped/Dependent
あなたの質問では言及されていませんが、(レガシー)JSFは @CustomScoped
および @NoneScoped
もサポートしています。これらは実際にはほとんど使用されません。 Beanの作成や破棄をよりきめ細かく制御するために、@CustomScoped
は、Map#put()
やMap#get()
をオーバーライドした、より広いスコープのカスタムMap<K, Bean>
実装を参照する必要があります。
JSFの@NoneScoped
およびCDI @Dependent
は、基本的にBeanの単一のEL評価まで有効です。 Beanプロパティを参照する2つの入力フィールドとBeanアクションを参照するコマンドボタンを持つログインフォームを想像してください。したがって、合計3つのEL式で、事実上3つのインスタンスが作成されます。ユーザー名が設定されたもの、パスワードが設定されたもの、アクションが呼び出されるもの。通常、このスコープを使用するのは、注入されるBeanが存続する限り有効なBeanのみです。したがって、@NoneScoped
または@Dependent
が@SessionScoped
に挿入された場合、@SessionScoped
Beanが存続する限り有効です。
最後に、JSFはフラッシュスコープもサポートします。これは、セッションスコープのデータエントリに関連付けられた短い有効なCookieによってサポートされます。リダイレクトの前に、セッションスコープのデータエントリに一意に関連付けられた値を持つCookieがHTTP応答に設定されます。リダイレクト後、フラッシュスコープCookieの存在が確認され、Cookieに関連付けられたデータエントリがセッションスコープから削除され、リダイレクトされたリクエストのリクエストスコープに配置されます。最後に、CookieがHTTP応答から削除されます。このようにして、リダイレクトされたリクエストは、最初のリクエストで準備されたスコープデータをリクエストするためのアクセス権を持ちます。
これは実際にはマネージドBeanスコープとしては利用できません。つまり、@FlashScoped
のようなものはありません。フラッシュスコープは、マネージドBeanでは ExternalContext#getFlash()
、ELでは#{flash}
を介してマップとしてのみ使用できます。
JSF 2.x以降、4つのBeanスコープがあります。
- @SessionScoped
- @RequestScoped
- @ApplicationScoped
- @ViewScoped
セッションスコープ:セッションスコープは、セッションが確立されてからセッションが終了するまで持続します。 WebアプリケーションがHttpSessionオブジェクトのinvalidateメソッドを呼び出した場合、またはタイムアウトした場合、セッションは終了します。
RequestScope:要求スコープは短命です。 HTTP要求が送信されたときに開始し、応答がクライアントに送り返された後に終了します。マネージドBeanをリクエストスコープに入れると、リクエストごとに新しいインスタンスが作成されます。セッションスコープの格納にかかるコストが心配な場合は、リクエストスコープを検討する価値があります。
ApplicationScope:アプリケーションスコープはWebアプリケーションの全期間にわたって持続します。その範囲は、すべての要求とすべてのセッションで共有されます。単一のBeanをWebアプリケーションのすべてのインスタンスで共有する必要がある場合は、マネージドBeanをアプリケーションスコープに配置します。 Beanは、アプリケーションの任意のユーザーによって最初に要求されたときに構築され、Webアプリケーションがアプリケーションサーバーから削除されるまで存続します。
ViewScope:ビュースコープはJSF 2.0で追加されました。同じJSFページが再表示されている間、ビュースコープ内のBeanは存続します。 (JSF仕様では、JSFページのビューという用語を使用しています。)ユーザーが別のページに移動するとすぐに、Beanは範囲外になります。
要件に基づいて範囲を選択してください。
出典:David Geary&Cay HorstmannによるCore Java Server Faces 3rd Edition 51 - 54]