如何在开发中(如Eclipse)区分<some:element>是标签处理器还是组件处理器?
区分JSF标签处理器与组件处理器(Eclipse环境实操)
在开发中快速判断<some:element>是标签处理器(Tag Handler)还是组件处理器(Component Handler),可以通过以下几种实操方法:
1. 直接查看标签的TLD定义
在Eclipse里,对着标签名(比如<ui:include>)按Ctrl+左键,就能跳转到对应的标签库描述文件(TLD):
- 如果TLD里该标签用
<tag>定义且指定了handler-class,并且这个类继承自javax.faces.view.facelets.TagHandler,那就是标签处理器。比如<ui:include>对应的IncludeHandler就属于这类。 - 如果标签定义里关联了
component-type或component-class,或者对应的Handler类继承自ComponentHandler,那就是组件处理器。比如<ui:repeat>的RepeatHandler负责创建UIRepeat组件实例,属于组件处理器范畴。
2. 借助Eclipse的JSF提示
开启Eclipse的JSF支持后,把鼠标悬停在标签上:
- 组件处理器的提示信息会提到关联的JSF组件类(比如
UIRepeat),或者明确标注“Component”相关内容; - 标签处理器的提示只会说明标签的功能,不会涉及组件实例的创建。
3. 从运行时行为反推
两者的执行时机和生命周期完全不同,这也是最直观的验证方式:
- 组件处理器:会在JSF组件树中生成持久化的组件实例,全程参与JSF的生命周期(恢复视图、应用请求值等阶段都有它的影子)。比如
<ui:repeat>会根据数据项生成对应的子组件,每次请求都会同步组件状态。 - 标签处理器:仅在视图构建阶段执行,执行完就不会再参与后续生命周期,也不会在组件树中留下实例。比如
<ui:include>只是在构建视图时把外部页面内容嵌入进来,后续请求里它不会再触发。
为什么要区分?
《Mastering JavaServer Faces 2.2》(Anghel Leonard 著)第538页明确提到:
<ui:repeat>属于组件处理器,<ui:include>属于标签处理器。
忽略这个差异很容易踩坑:
- 比如在
<ui:include>里试图访问请求阶段才初始化的变量,会因为标签在视图构建时就执行,导致变量尚未赋值而抛出空指针; - 要是误把
<ui:repeat>当标签处理器处理,比如在视图构建阶段修改它的数据源,可能会出现数据不更新、重复渲染异常等问题。
内容的提问来源于stack exchange,提问作者Toru
相关产品推荐
相关产品推荐

