Tomcat是由容器与组件构成,而容器又是由子容器与组件构成,server容器由 service组成,service又由connector与engine组成,tomcat是用lifecycle来带容器与其组件启动和相关事件处理,
下面为lifecycle的接口源码:
public interface Lifecycle {
public static final String START_EVENT = "start";
public static final String BEFORE_START_EVENT = "before_start";
public static final String AFTER_START_EVENT = "after_start";
public static final String STOP_EVENT = "stop";
public static final String BEFORE_STOP_EVENT = "before_stop";
public static final String AFTER_STOP_EVENT = "after_stop";
public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
}
有六事件类型,主要就两类,启动与关闭,对于不同的事件类型会不同的事件响应
方法start与stop就是控制容器的状态,还是比较简单,其它三个方法都是与LifecycleListener有关,
下面就看看LifecycleListener接口源码:
public interface LifecycleListener {
public void lifecycleEvent(LifecycleEvent event);
}
这个简洁,只有lifecycleEvent()方法,它的作用在于事件响应。。。
看这两个接口的代码,其实就事件驱动模型,与swing的事件是类似,只不过在tomcat源码中可以看其实现过程,
在swing中,通常会在某一个组件中增加一个监听器,比如说addActionListener(new ActionListener());这个listener这是当某个事件发生时需要响应的,可以增加监听器的组件就是tomcat的容器,因此需要实现lefecycly接口,增加的listener就要实现LifecycleListener接口,具体是怎么通知了,tomcat交给LifecycleSupport类处理,此过程用到观察者模式,
下面是其源码:
public final class LifecycleSupport {
public LifecycleSupport(Lifecycle lifecycle) { super(); this.lifecycle = lifecycle; }
private Lifecycle lifecycle = null; private LifecycleListener listeners[] = new LifecycleListener[0];
public void addLifecycleListener(LifecycleListener listener)
{ synchronized (listeners) {
LifecycleListener results[] = new LifecycleListener[listeners.length + 1];
for (int i = 0; i < listeners.length; i++)
results[i] = listeners[i];
results[listeners.length] = listener; listeners = results;
}
}
public LifecycleListener[] findLifecycleListeners() { return listeners; }
public void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
LifecycleListener interested[] = null;
synchronized (listeners) {
interested = (LifecycleListener[]) listeners.clone(); }
for (int i = 0; i < interested.length; i++)
interested[i].lifecycleEvent(event);
}
public void removeLifecycleListener(LifecycleListener listener) {
synchronized (listeners) {
int n = -1;
for (int i = 0; i < listeners.length; i++) {
if (listeners[i] == listener) { n = i; break; } }
if (n < 0) return;
LifecycleListener results[] = new LifecycleListener[listeners.length - 1];
int j = 0; for (int i = 0; i < listeners.length; i++)
{ if (i != n) results[j++] = listeners[i]; }
listeners = results; } } }
每增加一个listener时, 数组的长度就加1,删除时就减1,这个很好理解,重点就在于 fireLifecycleEvent(String type, Object data)方法中,当容器触发某一事件时,就把事件类型传到此方法,而此方法根据此事件类型通知在容器所增加的listener,如下代码:
for (int i = 0; i < interested.length; i++)
interested[i].lifecycleEvent(event);
}
而在listener中就会根据事件类型做出响应 ,如下是一个listener中的代码段:
if (Lifecycle.START_EVENT.equals(event.getType())) {
System.out.println("Starting context.");
}
else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
System.out.println("Stopping context.");
}
}