Tomcat - 事件的监听机制:观察者模式
本文承接上文中Lifecycle中实现,引出Tomcat的监听机制。@pdai
引入
前几篇文章中,我们经常会涉及到Listener相关的内容,比如如下内容中;我们通过引入这些内容,来具体探讨事件监听机制。
- 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)) {
// @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();
}
}
}