初始与清理事件处理线程

处理每个事件前的初始化

一个事件监听器是在一个事件处理线程中执行的。有时,你必须在处理所有事件前初始该线程。

一个典型的例子是初始化认证所使用的线程。一些J2EE或Web容器将认证信息存储在局部存储器(local storage)线程中。这样,可以在需要的时候自动进行重复验证。

为了初始化事件处理线,必须在WEBINF/zk.xml文件[32]listener元素中注册一个是实现了org.zkoss.zk.ui.event.EventThreadInit接口的类。

一旦注册完毕,一个指定类的实例就会在主线程中被创建。然后,在处理其他事情之前,该实例的init方法就会在事件处理线程的上下文中被调用。

请注意构造程序(constructor)和init方法是在不同的线程中被调用的,因此开发人员可以从一个线程取得独立线程数据并传送给另外一个线程。

这里有一个 JBoss[33]的认证机制。在这个例子中,我们在构造程序中获取存储在Servlet线程中的信息。然后当init方法被调用时初始事件处理线程。

import java.security.Principal;
import org.jboss.security.SecurityAssociation;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventThreadInit;

public class JBossEventThreadInit implements EventThreadInit {
   private final Principal _principal;
   private final Object _credential;
   /** Retrieve info at the constructor, which runs at the servlet thread. */
   public JBossEventThreadInit() {
      _principal = SecurityAssociation.getPrincipal();
      _credential = SecurityAssociation.getCredential();
   }
   //-- EventThreadInit --//
   /** Initial the event processing thread at this method. */
   public void init(Component comp, Event evt) {
      SecurityAssociation.setPrincipal(_principal);
      SecurityAssociation.setCredential(_credential);
   }
}

然后,在WEB-INF/zk.xml文件中,你需要完成如下的配置:

<zk>
   <listener>
      <listener-class>JBossEventThreadInit</listener-class>
   </listener>
</zk>

处理完每个事件后清理

类似的,在处理完每个事件后你或许必须清理一个事件处理线程。

一个典型的例子是关闭事务处理,如果它没有被适时地关闭。

为了清理一个事件处理线程,你必须在WEBINF/zk.xml文件的listener元素中注册一个实现org.zkoss.zk.ui.event.EventThreadCleanup接口的监听类。

<zk>
   <listener>
      <listener-class>my.MyEventThreadCleanup</listener-class>
   <listener>
</zk>


[32] the Developer's Reference 的附录(Appendix B) 进行了详细描述。

[33] http://www.jboss.org