何时使用 ,标记文件,复合组件和/或自定义组件?

问题描述 投票:93回答:1

我最近开始使用带有Facelets的JSF 2.0,并且对于了解现有的<ui:include>和Facelets 1.x提供的其他模板技术的新复合组件感到困惑。

这些方法有什么区别?在功能上他们似乎提供相同的:<ui:param> vs <cc:attribute><ui:insert> + <ui:define> vs标记文件,重用现有模板。除了复合组件的语法和清晰的接口规范之外还有什么吗?性能可能不同吗?

jsf-2 facelets custom-component composite-component tagfile
1个回答
165
投票

这些方法有什么区别?

Facelet templates

如果要将主页面布局片段拆分为可重复使用的模板,请使用Facelet模板(如<ui:composition><ui:include><ui:decorate>)。例如。标题,菜单,内容,页脚等

例子:

Facelet tag files

如果要使用可重复使用的组件组以防止/最小化代码重复,请使用Facelet标记文件。例如。一组标签+输入+消息组件。与复合组件的主要区别在于,Facelet标记文件的输出不代表单个UIComponent,并且在某些情况下可能是复合组件不足时的唯一解决方案。通常,具有一个或多个传递托管bean属性的<ui:include><ui:param>(因此不是硬编码值)是包含文件最好是标记文件的信号。

例子:

Composite components

如果要使用纯XML创建单个且可重复使用的自定义UIComponent,则使用复合组件。这样的复合组件通常由一堆现有组件和/或HTML组成,并且物理地呈现为单个组件,并且应该绑定到单个bean属性。例如。由3个依赖的java.util.Date成分表示单个<h:selectOneMenu>属性的组件,或将<p:fileUpload><p:imageCropper>组合成单个<my:uploadAndCropImage>的组件,将单个自定义com.example.Image实体称为属性。

例子:

Custom components

每当使用Facelet标记文件或复合组件无法实现功能时,请使用自定义组件,因为标准/可用组件集中缺乏支持。可以在开源组件库的源代码中找到示例,例如PrimeFacesOmniFaces

Tag handlers

当您想要控制JSF组件树的构建而不是呈现HTML输出时,您应该使用标记处理程序而不是组件。

例子:

Example projects

以下是一些利用上述所有技术的示例项目。


性能可能不同吗?

从技术上讲,性能问题可以忽略不计。应根据具体的功能要求以及实现的最终抽象程度,可重用性和可维护性来做出选择。每种方法都有其明确的目的和限制。

但是,在构建/恢复视图期间,复合组件会产生很大的开销(具体来说:在保存/恢复视图状态期间)。而且,在旧版本的Mojarra中,复合组件在分配默认值时存在性能问题,这已经从2.1.13开始修复。此外,当memory leak用于方法表达式时,Mojarra有一个<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和更新版本,当-1未设置为javax.faces.PROJECT_STAGE时,MyFaces已经默认为Development

© www.soinside.com 2019 - 2024. All rights reserved.