401

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

@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped

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

4

2 に答える 2

514

序章

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


@Request/View/Flow/Session/ApplicationScoped

Bean は、単一の HTTP 要求と応答のサイクルの@RequestScoped間存続します (Ajax 要求も単一の HTTP 要求としてカウントされることに注意してください)。Bean は、ナビゲーション/リダイレクトなしで/を返すアクション メソッドを呼び出すポストバックによって同じ JSF ビューと対話している@ViewScoped限り存続します。Bean は、フロー構成ファイルに登録された指定されたビューのコレクションをナビゲートしている限り存続します。Bean は、確立された HTTP セッションの間存続します。Bean は、Web アプリケーションが実行されている限り存続します。CDIは基本的に のステレオタイプであるため、同じルールが適用されることに注意してください。nullvoid@FlowScoped@SessionScoped@ApplicationScoped@Model@Named @RequestScoped

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

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

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

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


@CustomScoped/NoneScoped/Dependent

あなたの質問には記載されていませんが、(レガシー) JSF は and もサポートして@CustomScoped@NoneScopedますが、これは現実の世界ではめったに使用されません。オーバーライドされた、および/またはBeanの作成および/または破棄をよりきめ細かく制御するために、より広い範囲で@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 でのみ使用します。したがって、@NoneScopedor@Dependentが に注入された場合、それはBean@SessionScopedと同じくらい存続します。@SessionScoped

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


フラッシュスコープ

最後に、JSF はフラッシュ スコープもサポートします。これは、セッション スコープのデータ エントリに関連付けられている有効期間の短い Cookie によって支えられています。リダイレクトの前に、セッション スコープ内のデータ エントリに一意に関連付けられた値を持つ Cookie が HTTP 応答に設定されます。リダイレクト後、フラッシュ スコープ Cookie の存在がチェックされ、Cookie に関連付けられたデータ エントリがセッション スコープから削除され、リダイレクトされたリクエストのリクエスト スコープに配置されます。最後に、HTTP 応答から Cookie が削除されます。このようにして、リダイレクトされたリクエストは、最初のリクエストで準備されたリクエストスコープのデータにアクセスできます。

これは、マネージド Bean スコープとして実際には使用できません。つまり、 などはありません@FlashScopedExternalContext#getFlash()フラッシュ スコープは、マネージド Bean および#{flash}ELでマップとしてのみ使用できます。

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

于 2011-08-11T19:50:31.503 に答える