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

本文承接上文中Lifecycle中实现,引出Tomcat的监听机制。@pdai

引入

前几篇文章中,我们经常会涉及到Listener相关的内容,比如如下内容中;我们通过引入这些内容,来具体探讨事件监听机制。

  • Lifecycle中出现的监听器

(老的版本中是LifecycleSupport接口)

public interface Lifecycle {
    /** 第1类:针对监听器 **/
    // 添加监听器
    public void addLifecycleListener(LifecycleListener listener);
    // 获取所以监听器
    public LifecycleListener[] findLifecycleListeners();
    // 移除某个监听器
    public void removeLifecycleListener(LifecycleListener listener);
    ...
}
1
2
3
4
5
6
7
8
9
10
  • 多个组件中出现监听器

对应到整体架构图中

对应到代码中

知识准备

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

观察者模式

观察者模式(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);
}
1
2
3
  • 监听事件
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());
    }
}
1
2
3
4
5
6
7
8
9
  • 事件源:
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);
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • 测试
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"));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Tomcat中监听机制(Server部分)

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

  • 首先要定义一个监听器,它有一个监听方法,用来接受一个监听事件
public interface LifecycleListener {
    /**
     * Acknowledge the occurrence of the specified event.
     *
     * @param event LifecycleEvent that has occurred
     */
    public void lifecycleEvent(LifecycleEvent event);
}
1
2
3
4
5
6
7
8
  • 监听事件, 由于它是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;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  • 事件源的接口和实现

事件源的接口:在Lifecycle中

public interface Lifecycle {
    /** 第1类:针对监听器 **/
    // 添加监听器
    public void addLifecycleListener(LifecycleListener listener);
    // 获取所以监听器
    public LifecycleListener[] findLifecycleListeners();
    // 移除某个监听器
    public void removeLifecycleListener(LifecycleListener listener);
    ...
}
1
2
3
4
5
6
7
8
9
10

事件源的实现: 在 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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  • 接下来是调用了

比如在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)) {
            // @pdai:看这里
            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();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

联系我

添加@pdai微信

PS:添加时请备注Java全栈,谢谢!