12

ビューにスコープ付きBeanに@PreDestroyアノテーション付きのメソッドがあり、別のメソッドにアノテーション付きがあり@PostConstructます。

この@PostConstructビュースコープのBeanを使用するページに移動するたびに、メソッドが適切に呼び出されます。

ただし、で新しいページ(このビュースコープBeanを使用しない)に移動する<h:link/>と、@PreDestroyメソッドが呼び出されることはありません。

ナビゲーションの場合だけで、URLやセッションの終了を手動で変更することについて話しているのではありません。

私が欠けているものは何ですか?

前もって感謝します

4

2 に答える 2

19

これは仕様によるものです。POSTアクションの結果、同じビューへのポストバックではないナビゲーションが発生した場合にのみ、すぐに破棄されます(つまり、アクションメソッドが返されないか、nullまたは、空の場合でもvoid十分に価値がStringあります)。

<h:link>、POSTアクションを呼び出さないGETリンクを生成します。ビューがアンロードされたときに(XML)HTTP要求によってサーバー側に通知することは確実に不可能であるため、ビューに関連付けられたビュースコープのBeanを破棄するようにJSFに通知することはできません。このような場合、ビュースコープBeanは、セッションが期限切れになるか、セッションの最大論理ビュー(デフォルトは15)を超え、関連付けられたビューが最初に表示された場合にのみ破棄されます。

ナビゲーションアクションによってビュースコープのBeanを本当に破棄したい場合は、代わりにPOSTリクエストを作成し、パラメータを使用<h:commandLink>してナビゲーション結果を返すことでリダイレクトを発行するのが最善の策です。?faces-redirect=trueしかし、ボットはPOSTリンクのインデックスを作成しないため、これは結局SEOに適していません。

結局のところ、私はビューがまだセッションにあることを気にしません。クリーンアップやロギングを行う場合は、具体的な機能要件に応じて、別の方法を探します。

理論的にはHTMLDOMonbeforeunloadイベントによって可能になりますが、これは非標準のイベントであり、そのイベント中にajaxリクエストを送信したときに何が起こるかについてブラウザーの動作は指定されていません。到着することもありますが、到着しないこともあります。

更新実際には、これはOmniFaces2.2@ViewScoped以降OmniFacesに実装されています。最初は同期XHRの助けを借りて、そしてOmniFaces2.6以降はビーコンの助けを借りて。主要なブラウザで非常にうまく機能しています。OmniFaces 2.3以降は、関連するJSFサーバー側のビュー状態を即座に破棄し、OmniFaces 2.6以降は、物理Beanも即座に破棄するため、不要なメモリ使用量がさらに削減されます。特にJSF:Mojarra vs. OmniFaces @ViewScoped:@PreDestroyが呼び出されましたが、Beanをガベージコレクションすることはできません。

于 2012-01-05T16:43:19.190 に答える
1

JSF2.2CDI互換の@ViewScopedBean(javax.faces.view.ViewScoped)が、さまざまなナビゲーションケース(Mojarra 2.2.9、Glassfish4、NetBeans8.0.2、JDK1)でガベージコレクション用にリリースされる時期を示す小さなNetBeansプロジェクトを準備しました。 .7)、ここからダウンロードできますここではコードが省略されています。ダウンロードをご覧ください。

処理されたナビゲーションケースと結果は、次の画像に要約されています。

完了したランディングページへのJSFナビゲーションケースで@ViewSCopedBeanを使用したインデックスページを示す画像

@ViewScoped Beanを監視するには、Glassfish(またはミニプロジェクトに組み込まれているNetBeansプロファイラー)に対してVisualVMを使用し、パッケージ名「webel.com.jsf」でサンプラーメモリヒープヒストグラムクラスビューをフィルタリングします。次の画像は、h:link、ブラウザーURL GET、およびブラウザーRELOAD GETを大量に試した後の、webel.com.jsf.Jsf22ViewBeanの不条理な66インスタンスを示しています。これらのインスタンスは、ガベージコレクションされません(VisualVM Perform GCを使用してテストできます)。ボタン):

ここに画像の説明を入力してください

比較すると、h:commandButtonとアクションメソッド式またはアクション文字列により、@ ViewScoped Beanがガベージコレクション用に解放されます(WeldClientProxyから@ViewScoped Beanへの参照は常に1つあり、h:commandButtonを使用して前後に移動すると、WeldClientProxyは1つの解放可能なBeanから次のBeanに移動します) 。

于 2015-05-23T08:03:04.250 に答える