1. ホーム
  2. jsf

[解決済み] ビーンスコープを正しく選ぶには?

2022-03-24 08:03:53

質問

Beanのスコープには、以下のような種類があることに気づきました。

@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped

それぞれの目的は何ですか?ビーンに適したスコープを選ぶにはどうしたらよいですか?

どのように解決するのですか?

はじめに

Beanのスコープ(寿命)を表します。これは、基本的なサーブレットWebアプリケーションの動作に慣れている人であれば、理解しやすいでしょう。 サーブレットはどのように動作するのか?インスタンス化、セッション、共有変数、マルチスレッド .


@Request/View/Flow/Session/ApplicationScoped

A @RequestScoped ビーンは、1回のHTTPリクエスト-レスポンスサイクルと同じくらい長く生きています (Ajaxリクエストも1回のHTTPリクエストとしてカウントされることに注意してください)。A @ViewScoped を返すアクションメソッドを呼び出すポストバックによって、 同じ JSF ビューとやりとりしている限りは、ビーンは生き続けます。 null / void ナビゲーション/リダイレクトなしで A @FlowScoped ビーンは、フロー設定ファイルに登録された指定されたビューのコレクションをナビゲートしている限り、生き続けます。A @SessionScoped ビーンは、確立されたHTTPセッションと同じ時間だけ存続します。また @ApplicationScoped ビーンは、ウェブアプリケーションが実行されている限り存続します。CDI @Model は基本的に ステレオタイプ に対して @Named @RequestScoped ということで、同じルールが適用されます。

どのスコープを選択するかは、ビーンが保持し、表現するデータ(状態)のみに依存します。使用する @RequestScoped 単純で非Ajaxのフォーム/プレゼンテーションの場合。使用方法 @ViewScoped リッチなajax対応ダイナミックビュー(ajaxベースの検証、レンダリング、ダイアログなど)用。使用方法 @FlowScoped 複数のページにまたがって入力データを収集するウィザード(アンケート)のパターンに使用します。使用方法 @SessionScoped ログインしているユーザーやユーザー設定(言語など)のようなクライアント固有のデータに使用します。使用方法 @ApplicationScoped アプリケーション全体のデータ/定数に使用します。例えば、誰に対しても同じドロップダウンリストや、 インスタンス変数を持たずメソッドのみを持つマネージドビーンなどです。

を悪用した @ApplicationScoped ビーンをセッション/ビュー/リクエストのスコープで使用すると、すべてのユーザー間でデータを共有することになります。また @SessionScoped そのため、タブを切り替えた後にすべてのビューを操作すると、エンドユーザーが矛盾を経験する可能性があり、ユーザーエクスペリエンスにとってよくありません。また @RequestScoped ビーンをビュースコープデータに使用すると、(ajax)ポストバックのたびにビュースコープデータがデフォルトに再初期化され、動作しないフォームが生じる可能性があります ( 4と5を参照してください。 ). を悪用した @ViewScoped ビーンをリクエスト、セッション、またはアプリケーションのスコープ付きデータに対して使用し @SessionScoped アプリケーションスコープのデータ用のビーンは、クライアントには影響しませんが、不必要にサーバーメモリを占有しており、明らかに非効率です。

スコープを選択する際に、パフォーマンスへの影響を考慮してはならないことに注意してください。 本当に は、メモリフットプリントが小さく、完全にステートレスにしたい場合、専ら @RequestScoped ビーンとリクエストパラメータを操作して、クライアントの状態を維持します。また、異なるスコープのデータを持つ単一のJSFページがある場合、データのスコープに一致するスコープで別々のバッキングビーンに置くことは完全に有効であることに注意してください。Beanは @ManagedProperty JSFマネージドビーンズの場合、または @Inject CDIマネージドビーンズの場合。

こちらもご覧ください。


@CustomScoped/NoneScoped/Dependent

質問には書かれていませんが、(レガシーな)JSFでも @CustomScoped @NoneScoped という、現実世界ではほとんど使われないような その @CustomScoped は、カスタム Map<K, Bean> をオーバーライドした、より広いスコープでの実装です。 Map#put() および Map#get() を使用することで、ビーンの生成や破棄をより細かく制御することができます。

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

こちらもご覧ください。


フラッシュスコープ

最後に、JSFはフラッシュスコープもサポートしています。これは、セッションスコープのデータエントリーに関連付けられた、短い生活クッキーによって支えられています。リダイレクトの前に、クッキーは、セッションスコープのデータエントリーに一意に関連付けられた値で、HTTPレスポンスに設定されます。リダイレクト後、フラッシュスコープのクッキーの存在が確認され、そのクッキーに関連付けられたデータエントリはセッションスコープから削除され、リダイレクトされたリクエストのリクエストスコープに入れられます。最後に、クッキーはHTTPレスポンスから削除されます。このようにして、リダイレクトされたリクエストは、最初のリクエストで準備されたリクエストスコープのデータにアクセスすることができます。

これは実はマネージドビーンズのスコープとして利用できない、すなわち @FlashScoped . フラッシュスコープがマップとして利用できるのは ExternalContext#getFlash() マネージドビーン内の #{flash} をELで使用します。

こちらもご覧ください。