Home   Single Page

各イベントを処理する前に初期化

イベント処理スレッドの中でイベントリスナは実行されます。イベントを処理する前にスレッドを初期化しなければならない場合もあります。

代表的な例はユーザー認証スレッドの初期化です。一部のJ2EE又はウェブコンテナは、ユーザー認証用の情報をスレッドローカルメモリに保存し、必要なときに自動的に最認証できるようにしています。

イベント処理スレッドを初期化するのに、org.zkoss.zk.ui.event.EventThreadInitインターフェイスを実装するクラスをWEB-INF/zk.xmlファイルのlistener 要素に登録しなければなりません[32]。

登録できたら、指定したクラスのインスタンスはイベント処理スレッドが始まる前に、メインスレッドに構築されます(aka.、サーブレッドスレッド)。そして、何よりも先に、インスタンスのinitメソッドはイベント処理のコンテキストで呼び出されます。

コンストラクタとinitコマンドは異なったスレッドの中に呼び出されて、開発者はスレッド依存するデータをひとつのスレッドから取得し、他へ送ります。

ここにJBossのユーザー認証メカニズムの例をあげます[33]。この例では、コンストラクタの中のサーブレッドスレッドに保存されている情報を取得します。そうして、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>


[32] 詳細は開発用リファレンスのAppendix Bを参照してください。

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