JSF2 以编程方式取消订阅全局系统事件侦听器
Posted
技术标签:
【中文标题】JSF2 以编程方式取消订阅全局系统事件侦听器【英文标题】:JSF2 unsubscribe a global system event listener programmatically 【发布时间】:2013-07-04 07:23:13 【问题描述】:有没有办法在 JSF2 中以编程方式取消订阅由第三方 (jsf 2 ) 相关 jar 通过其自己的 faces-config.xml 添加的全局系统事件侦听器?
我知道javax.faces.application.Application
(http://docs.oracle.com/javaee/6/api/index.html?javax/faces/application/Application.html) 中有两种方法可以取消订阅,其中之一是unsubscribeFromEvent(java.lang.Class<? extends SystemEvent> systemEventClass, java.lang.Class<?> sourceClass, SystemEventListener listener)
。
上述方法的前两个参数很好,但是我们如何获取之前注册的监听器对象。
为什么我需要取消订阅,以便为侦听器提供自定义行为。这也可以通过 PostConstructApplicationEvent (http://docs.oracle.com/javaee/6/api/javax/faces/event/PostConstructApplicationEvent.html) 类型的系统事件的另一个全局系统事件侦听器来完成吗?
需要:我们在基于 Web 的项目中大量使用 Prime Faces (PF) 和 Omni Faces (OF)。在 PF 中,我们稍微定制了 DataTable 和 DataTableRenderer,以便在 header 和 tbody 部分中对静态和动态列进行复杂的混合。最近我移植到 PF 版本 4 并且一切正常,但最近 PF 快照添加了一个名为 DynamicColumnsListener 的新系统事件监听器,这个监听器的行为给我们带来了问题。这就是为什么我需要取消订阅这个监听器并为我实现的扩展提供我自己的自定义监听器。
更新:PrimeFaces事件监听DynamicColumnsListener的processEvent方法的实现是
Columns columns = (Columns) event.getSource();
((DataTable) columns.getParent()).setDynamicColumns(columns);
根据 DataTable 和 DataTableRenderer 的 PrimeFaces 实现,这一切都很好,但在我的扩展中,我也可以在“标题”方面有动态列,然后它的父级是 org.primefaces.component.row.Row 而不是 DataTable 所以它遇到 ClassCastException,因为它在标题方面的父级不是 DataTable 而是 Row。
【问题讨论】:
告诉你为什么需要这个也许是一个更好的主意,然后我们可以从 OmniFaces 端对其进行配置。 刚刚按照 BalusC 的建议更新了问题 哦,对了,问题出在 PrimeFaces 方面,而不是在 OmniFaces 方面。我将删除 OmniFaces 标记。 是的,它在 PrimeFaces 方面,但从他们的角度来看并不是一个真正的问题,但是是的,这对我的扩展程序来说是一个问题,因此寻找一种通用的方式来取消订阅全局系统事件侦听器。 据我所知,很遗憾这是不可能的。您可能希望以这样的方式重新构建您的问题,只告诉您在使用 PrimeFaces 事件侦听器时遇到的问题并询问如何解决。 【参考方案1】:在这种特定情况下,您可以只覆盖 Columns 组件。
package com.company;
public class Columns extends org.primefaces.component.columns.Columns
在 faces-config.xml 中:
<component>
<component-type>org.primefaces.component.Columns</component-type>
<component-class>com.company.Columns</component-class>
</component>
由于 DynamicColumnsListener 专门附加到 org.primefaces.component.columns.Columns
,因此它不适用于被覆盖的组件。
或者也许您可以使用反射技巧获取侦听器实例,例如致电 Mojarra 的com.sun.faces.application.ApplicationImpl#getListeners
。
【讨论】:
以上是关于JSF2 以编程方式取消订阅全局系统事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章
事件侦听和删除事件——event对象——按钮精灵——默认事件——取消冒泡事件——事件委托——默认触发——onload 图片预加载四个迭代版本