当前位置: 代码网 > 服务器>服务器>Linux > Tomcat的事件监听机制:观察者模式详解

Tomcat的事件监听机制:观察者模式详解

2026年04月28日 Linux 我要评论
lifecycle中出现的监听器(老的版本中是lifecyclesupport接口)public interface lifecycle { /** 第1类:针对监听器 **/ // 添加

lifecycle中出现的监听器

(老的版本中是lifecyclesupport接口)

public interface lifecycle {
    /** 第1类:针对监听器 **/
    // 添加监听器
    public void addlifecyclelistener(lifecyclelistener listener);
    // 获取所以监听器
    public lifecyclelistener[] findlifecyclelisteners();
    // 移除某个监听器
    public void removelifecyclelistener(lifecyclelistener listener);
    ...
}
  • 多个组件中出现监听器

对应到整体架构图中

对应到代码中

知识准备

理解上述监听器的需要你有些知识储备,一是设计模式中的观察者模式,另一个是事件监听机制。

观察者模式

观察者模式(observer pattern): 在对象之间定义一对多的依赖, 这样一来, 当一个对象改变状态, 依赖它的对象都会收到通知, 并自动更新

主题(subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。

观察者(observer)的注册功能需要调用主题的 registerobserver() 方法。

详情请参考 设计模式:行为型 - 观察者(observer)

事件监听机制

jdk 1.0及更早版本的事件模型基于职责链模式,但是这种模型不适用于复杂的系统,因此在jdk 1.1及以后的各个版本中,事件处理模型采用基于观察者模式的委派事件模型(delegationevent model, dem),即一个java组件所引发的事件并不由引发事件的对象自己来负责处理,而是委派给独立的事件处理对象负责。这并不是说事件模型是基于observer和observable的,事件模型与observer和observable没有任何关系,observer和observable只是观察者模式的一种实现而已。

java中的事件机制的参与者有3种角色

  • event eource:事件源,发起事件的主体。
  • event object:事件状态对象,传递的信息载体,就好比watcher的update方法的参数,可以是事件源本身,一般作为参数存在于listerner 的方法之中。
  • event listener:事件监听器,当它监听到event object产生的时候,它就调用相应的方法,进行处理。

其实还有个东西比较重要:事件环境,在这个环境中,可以添加事件监听器,可以产生事件,可以触发事件监听器。

这个和观察者模式大同小异,但要比观察者模式复杂一些。一些逻辑需要手动实现,比如注册监听器,删除监听器,获取监听器数量等等,这里的eventobject也是你自己实现的。

下面我们看下java中事件机制的实现,理解下面的类结构将帮助你tomcat中监听机制的实现。

  • 监听器
public interface eventlistener extends java.util.eventlistener {
    void handleevent(eventobject event);
}
  • 监听事件
public class eventobject extends java.util.eventobject{
    private static final long serialversionuid = 1l;
    public eventobject(object source){
        super(source);
    }
    public void doevent(){
        system.out.println("通知一个事件源 source :"+ this.getsource());
    }
}
  • 事件源:
public class eventsource {
    //监听器列表,监听器的注册则加入此列表
    private vector<eventlistener> listenerlist = new vector<>();
    //注册监听器
    public void addlistener(eventlistener eventlistener) {
        listenerlist.add(eventlistener);
    }
    //撤销注册
    public void removelistener(eventlistener eventlistener) {
        listenerlist.remove(eventlistener);
    }
    //接受外部事件
    public void notifylistenerevents(eventobject event) {
        for (eventlistener eventlistener : listenerlist) {
            eventlistener.handleevent(event);
        }
    }
}
  • 测试
public static void main(string[] args) {
    eventsource eventsource = new eventsource();
    eventsource.addlistener(new eventlistener() {
        @override
        public void handleevent(eventobject event) {
            event.doevent();
            if (event.getsource().equals("closewindows")) {
                system.out.println("doclose");
            }
        }
    });
    eventsource.addlistener(new eventlistener() {
        @override
        public void handleevent(eventobject event) {
            system.out.println("gogogo");
        }
    });
    /*
      * 传入openwindows事件,通知listener,事件监听器,
      对open事件感兴趣的listener将会执行
      **/
    eventsource.notifylistenerevents(new eventobject("openwindows"));
}

tomcat中监听机制(server部分)

基于上面的事件监听的代码结构,你就能知道tomcat中事件监听的类结构了。

  • 首先要定义一个监听器,它有一个监听方法,用来接受一个监听事件
public interface lifecyclelistener {
    /**
     * acknowledge the occurrence of the specified event.
     *
     * @param event lifecycleevent that has occurred
     */
    public void lifecycleevent(lifecycleevent event);
}
  • 监听事件, 由于它是lifecycle的监听器,所以它握有一个lifecycle实例
/**
 * general event for notifying listeners of significant changes on a component
 * that implements the lifecycle interface.
 *
 * @author craig r. mcclanahan
 */
public final class lifecycleevent extends eventobject {
    private static final long serialversionuid = 1l;
    /**
     * construct a new lifecycleevent with the specified parameters.
     *
     * @param lifecycle component on which this event occurred
     * @param type event type (required)
     * @param data event data (if any)
     */
    public lifecycleevent(lifecycle lifecycle, string type, object data) {
        super(lifecycle);
        this.type = type;
        this.data = data;
    }
    /**
     * the event data associated with this event.
     */
    private final object data;
    /**
     * the event type this instance represents.
     */
    private final string type;
    /**
     * @return the event data of this event.
     */
    public object getdata() {
        return data;
    }
    /**
     * @return the lifecycle on which this event occurred.
     */
    public lifecycle getlifecycle() {
        return (lifecycle) getsource();
    }
    /**
     * @return the event type of this event.
     */
    public string gettype() {
        return this.type;
    }
}
  • 事件源的接口和实现

事件源的接口:在lifecycle中

public interface lifecycle {
    /** 第1类:针对监听器 **/
    // 添加监听器
    public void addlifecyclelistener(lifecyclelistener listener);
    // 获取所以监听器
    public lifecyclelistener[] findlifecyclelisteners();
    // 移除某个监听器
    public void removelifecyclelistener(lifecyclelistener listener);
    ...
}

事件源的实现: 在 lifecyclebase 中

 /**
  * the list of registered lifecyclelisteners for event notifications.
  */
private final list<lifecyclelistener> lifecyclelisteners = new copyonwritearraylist<>();
/**
  * {@inheritdoc}
  */
@override
public void addlifecyclelistener(lifecyclelistener listener) {
    lifecyclelisteners.add(listener);
}
/**
  * {@inheritdoc}
  */
@override
public lifecyclelistener[] findlifecyclelisteners() {
    return lifecyclelisteners.toarray(new lifecyclelistener[0]);
}
/**
  * {@inheritdoc}
  */
@override
public void removelifecyclelistener(lifecyclelistener listener) {
    lifecyclelisteners.remove(listener);
}
/**
  * allow sub classes to fire {@link lifecycle} events.
  *
  * @param type  event type
  * @param data  data associated with event.
  */
protected void firelifecycleevent(string type, object data) {
    lifecycleevent event = new lifecycleevent(this, type, data);
    for (lifecyclelistener listener : lifecyclelisteners) {
        listener.lifecycleevent(event);
    }
}
  • 接下来是调用了

比如在lifecyclebase, 停止方法是基于lifecyclestate状态改变来触发上面的firelifecycleevent方法:

@override
public final synchronized void stop() throws lifecycleexception {
    if (lifecyclestate.stopping_prep.equals(state) || lifecyclestate.stopping.equals(state) ||
            lifecyclestate.stopped.equals(state)) {
        if (log.isdebugenabled()) {
            exception e = new lifecycleexception();
            log.debug(sm.getstring("lifecyclebase.alreadystopped", tostring()), e);
        } else if (log.isinfoenabled()) {
            log.info(sm.getstring("lifecyclebase.alreadystopped", tostring()));
        }
        return;
    }
    if (state.equals(lifecyclestate.new)) {
        state = lifecyclestate.stopped;
        return;
    }
    if (!state.equals(lifecyclestate.started) && !state.equals(lifecyclestate.failed)) {
        invalidtransition(lifecycle.before_stop_event);
    }
    try {
        if (state.equals(lifecyclestate.failed)) {
            // 看这里
            firelifecycleevent(before_stop_event, null);
        } else {
            setstateinternal(lifecyclestate.stopping_prep, null, false);
        }
        stopinternal();
        // shouldn't be necessary but acts as a check that sub-classes are
        // doing what they are supposed to.
        if (!state.equals(lifecyclestate.stopping) && !state.equals(lifecyclestate.failed)) {
            invalidtransition(lifecycle.after_stop_event);
        }
        setstateinternal(lifecyclestate.stopped, null, false);
    } catch (throwable t) {
        handlesubclassexception(t, "lifecyclebase.stopfail", tostring());
    } finally {
        if (this instanceof lifecycle.singleuse) {
            // complete stop process first
            setstateinternal(lifecyclestate.stopped, null, false);
            destroy();
        }
    }
}

到此这篇关于tomcat的事件监听机制:观察者模式详解的文章就介绍到这了,更多相关tomcat事件监听机制内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com