Answers:
这些方法之间有什么区别?
使用模板的facelet(如<ui:composition>
,<ui:include>
和<ui:decorate>
如果要将主页布局片段拆分为可重复)。例如页眉,菜单,内容,页脚等。
例子:
如果要具有一组可重用的组件,请使用Facelet标记文件,以防止/减少代码重复。例如一组标签+输入+消息组件。复合组件的主要区别在于,Facelet标记文件的输出不代表单个UIComponent
,在某些情况下可能是复合组件不足的唯一解决方案。通常,具有<ui:include>
一个或多个<ui:param>
通过托管Bean属性(因此不是硬编码值)的信号表明,包含文件可以更好地是标记文件。
例子:
如果您要UIComponent
使用纯XML 来创建具有单一职责的单一可重用定制,请使用复合组件。这种复合组件通常由一堆现有组件和/或HTML组成,并在物理上呈现为单个组件,并且应该绑定到单个bean属性。例如,java.util.Date
由3个从属<h:selectOneMenu>
组件表示单个属性的组件,或将一个自定义实体作为属性进行组合<p:fileUpload>
并组合<p:imageCropper>
成单个组件的组件。<my:uploadAndCropImage>
com.example.Image
例子:
每当Facelet标记文件或复合组件无法实现功能时,都要使用自定义组件,这是因为标准/可用组件集中缺乏支持。在诸如PrimeFaces和OmniFaces之类的开源组件库的源代码中,到处都有示例。
当您要控制JSF组件树的构建而不是HTML输出的呈现时,则应使用标记处理程序而不是组件。
例子:
这是一些利用所有上述技术的示例项目。
性能会有所不同吗?
从技术上讲,性能问题可以忽略不计。选择应基于具体的功能要求以及实现的最终抽象程度,可重用性和可维护性。每种方法都有其明确定义的目的和局限性。
但是,复合组件在构建/还原视图期间(特别是在保存/还原视图状态期间)确实会产生大量开销。而且,在Mojarra的旧版本中,复合组件在分配默认值方面存在性能问题,此问题自2.1.13开始已得到修复。同样,当使用a 表示方法表达式时,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及更高版本,并且MyFaces已经默认设置为-1
when javax.faces.PROJECT_STAGE
未设置为Development
。
NamingContainer
,否则当同一组件多次重复使用时,您将遇到重复的ID问题。
Image
属性在豆子里。