107

<ui:include>最近、FaceletsでJSF 2.0を使い始めましたが、Facelets1.xが提供する既存のテンプレート技術やその他のテンプレート技術を知っている新しい複合コンポーネントに戸惑いました。

これらのアプローチの違いは何ですか?機能的には、ほぼ同じものを提供しているようです:<ui:param>vs <cc:attribute><ui:insert>+ <ui:define>vsタグファイル、既存のテンプレートの再利用。複合コンポーネントの場合、構文と明確なインターフェイス仕様以外に何かありますか?パフォーマンスは異なりますか?

4

1 に答える 1

182

これらのアプローチの違いは何ですか?

Facelet テンプレート

メイン ページ レイアウトの断片を再利用可能なテンプレートに分割する場合は、 Facelet テンプレートを使用します ( <ui:composition><ui:include>および のように)。<ui:decorate>例: ヘッダー、メニュー、コンテンツ、フッターなど。

例:

Facelet タグファイル

コードの重複を防止/最小化するために再利用可能なコンポーネントのグループが必要な場合は、Facelet タグ ファイルを使用します。たとえば、label+input+message コンポーネントのグループです。複合コンポーネントとの主な違いは、Facelet タグ ファイルの出力は 1 つではなく、UIComponent状況によっては、複合コンポーネントでは不十分な場合に唯一の解決策になる可能性があることです。一般に、マネージド Bean プロパティを渡す<ui:include>1 つ以上<ui:param>の (したがって、ハードコードされた値ではない) を持つことは、インクルード ファイルがタグ ファイルであるほうがよいというシグナルです。

例:

複合部品

UIComponent純粋な XML を使用して、単一の責任を持つ単一の再利用可能なカスタムを作成する場合は、複合コンポーネントを使用します。このような複合コンポーネントは、通常、多数の既存のコンポーネントや HTML で構成され、単一のコンポーネントとして物理的にレンダリングされ、単一の Bean プロパティにバインドされることになっています。たとえば、日、月、年を表すjava.time.LocalDate3 つの依存コンポーネントによって単一のプロパティを表すコンポーネント、または単一のカスタムエンティティをプロパティとして参照する単一のコンポーネントに<h:selectOneMenu>結合するコンポーネントです。<p:fileUpload><p:imageCropper><my:uploadAndCropImage>com.example.Image

例:

カスタム コンポーネント

コンポーネントの標準/利用可能なセットがサポートされていないために、Facelet タグ ファイルまたは複合コンポーネントで機能を実現できない場合は常に、カスタム コンポーネントを使用してください。一般に、デコードおよび/またはエンコードの高度な制御および/またはカスタマイズが必要な場合、およびエンドユーザーにデコードおよび/またはエンコードを比較的簡単に拡張/オーバーライドする可能性を提供する場合。例は、 PrimeFacesOmniFacesなどのオープン ソース コンポーネント ライブラリのソース コードのいたるところにあります。

タグ ハンドラ

HTML 出力のレンダリングではなく、JSF コンポーネント ツリーの構築を制御する場合は、コンポーネントの代わりにタグ ハンドラを使用する必要があります。

例:

サンプルプロジェクト

上記の手法をすべて利用したプロジェクトの例をいくつか示します。


パフォーマンスが異なる可能性はありますか?

技術的には、パフォーマンスの問題は無視できます。選択は、具体的な機能要件と、実装の最終的な抽象度、再利用性、保守性に基づいて行う必要があります。各アプローチには、明確に定義された独自の目的と制限があります。

ただし、複合コンポーネントには、ビューの構築/復元中 (具体的には、ビュー状態の保存/復元中) に大きなオーバーヘッドがあります。また、Mojarra の古いバージョンでは、複合コンポーネントにデフォルト値の割り当てに関するパフォーマンスの問題がありましたが、これは 2.1.13 以降で既に修正されています。また、Mojarra ではメソッド式に aを使用するとメモリ リークが発生<cc:attribute method-signature>しました。基本的にコンポーネント ツリー全体が HTTP セッションで再参照されます。これは 2.1.29 / 2.2.8 以降で修正されています。古い 2.1 バージョンでは、次のようにメモリ リークを回避できます。

<context-param>
    <param-name>com.sun.faces.serializeServerState</param-name>
    <param-value>true</param-value>
</context-param>

または、以下の古い 2.2 バージョンでは:

<context-param>
    <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
    <param-value>true</param-value>
</context-param>

それでも、比較的「多くの」複合コンポーネントがあり、 にjavax.faces.STATE_SAVING_METHOD設定したclient場合、パフォーマンスは苦痛になります。単純なインクルード ファイルまたはタグ ファイルですでに可能になっている基本的な機能が必要なだけの場合は、複合コンポーネントを悪用しないでください。*.taglib.xmlタグファイルよりも複合コンポーネントを好む言い訳として、構成の容易さ (ファイルは必要ありません) を使用しないでください。

Mojarra 2.2.10 以前を使用している場合は、プロダクション モードの比較的短い Facelets の更新期間を無効にすることを忘れないでください。

<context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>-1</param-value>
</context-param>

この設定を開発に使用しないでください。そうしないと、Facelets ファイルの変更を反映するためにサーバー全体を再起動する必要があります。Mojarra 2.2.11 以降、および MyFacesは、 が に設定されていない-1場合、すでにデフォルトで に設定されています。javax.faces.PROJECT_STAGEDevelopment

于 2011-07-25T20:58:04.530 に答える