web-dev-qa-db-ja.com

<ui:include>、タグファイル、複合コンポーネント、カスタムコンポーネントを使用する場合

最近、私はFaceletsでJSF 2.0を使い始めましたが、既存の<ui:include>およびFacelets 1.xが提供するその他のテンプレート技術。

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

94
mrembisz

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

Faceletテンプレート

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

例:

Faceletタグファイル

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

例:

複合コンポーネント

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

例:

カスタムコンポーネント

Faceletタグファイルまたは複合コンポーネントで機能を実現できない場合は、標準/利用可能なコンポーネントセットのサポートがないため、カスタムコンポーネントを使用します。 PrimeFacesOmniFaces などのオープンソースコンポーネントライブラリのソースコードのすべての場所にサンプルがあります。

タグハンドラー

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

例:

サンプルプロジェクト

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


パフォーマンスに違いはありますか?

技術的には、パフォーマンスの問題はごくわずかです。具体的な機能要件と、実装の抽象化、再利用性、および保守性の最終的な程度に基づいて選択する必要があります。各アプローチには、明確な目的と制限があります。

ただし、複合コンポーネントには、ビューの構築/復元中(特に、ビューステートの保存/復元中)に大きなオーバーヘッドがあります。また、Mojarraの古いバージョンでは、複合コンポーネントにデフォルト値の割り当てに関するパフォーマンスの問題がありましたが、これは2.1.13以降ですでに修正されています。また、<cc:attribute method-signature>がメソッド式に使用される場合、Mojarraには メモリリーク があり、基本的にコンポーネントツリー全体が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_METHODclientに設定している場合、パフォーマンスが低下します。単純なインクルードファイルまたはタグファイルで既に可能な基本的な機能だけが必要な場合は、複合コンポーネントを乱用しないでください。タグファイルよりも複合コンポーネントを優先する言い訳として、構成の容易さ(読み取り:*.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以降、および-1Developmentに設定されていない場合、MyFacesはすでにデフォルトでjavax.faces.PROJECT_STAGEに設定されています。

167
BalusC