本文接下来描述servlet容器是怎样管理其相关组件的生命周期的,首先本人描述一下事件监听模式,也可以称为观察者模式,该模式分为以下角色
即抽象主题角色 具体主题角色 抽象观察者角色及具体观察者角色,通常在主题角色里面维持一个观察者角色的聚集,并定义了对观察者角色的添加和删除方法;在主题角色事件发生时,通过迭代向这些观察者角色发布事件。
在tomcat容器中,管理其相关组件的生命周期即是基于事件监听模式实现的,相关接口和类为org.apache.catalina.Lifecycle接口、org.apache.catalina.LifecycleListener接口、org.apache.catalina.LifecycleEvent类
org.apache.catalina.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; }
上面的六个静态字符串代表六种类型的事件,接着的三个方法addLifecycleListener()、 findLifecycleListeners()、removeLifecycleListener()为与事件监听器相关的,最后的两个方法start()和stop()为启动与关闭操作,组件必须提供这两种方法的实现,供其父组件调用。
org.apache.catalina.LifecycleEvent类用于传递事件及携带事件数据
public final class LifecycleEvent
extends EventObject { public LifecycleEvent(Lifecycle lifecycle, String type) {
this(lifecycle, type, null);
} public LifecycleEvent(Lifecycle lifecycle, String type, Object data) { super(lifecycle);
this.lifecycle = lifecycle;
this.type = type;
this.data = data;
} private Object data = null; private Lifecycle lifecycle = null; private String type = null; public Object getData() {
return (this.data);
} public Lifecycle getLifecycle() {
return (this.lifecycle);
} public String getType() {
return (this.type);
}
}
org.apache.catalina.LifecycleListener为监听器接口
public interface LifecycleListener { /**
* Acknowledge the occurrence of the specified event.
*
* @param event LifecycleEvent that has occurred
*/
public void lifecycleEvent(LifecycleEvent event); }
通常实现了Lifecycle接口并且对某个事件注册了监听器的组件必须提供 Lifecycle接口中三个与监听器相关方法(分别为addLifecycleListener()、 findLifecycleListeners()、removeLifecycleListener())的实现,然后该组件需要将所有注册的监听器存储到数组、ArrayList或者其他类似的对象中;tomcat容器提供了一个工具类org.apache.catalina.util.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;
}
}
}
下面我们来看Context容器(SimpleContext实例)是怎么实现生命周期管理及触发监听器事件的,关键代码如下
public class SimpleContext implements Context, Pipeline, Lifecycle { protected LifecycleSupport lifecycle = new LifecycleSupport(this); // implementation of the Lifecycle interface's methods
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
} public LifecycleListener[] findLifecycleListeners() {
return null;
} public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
} public synchronized void start() throws LifecycleException {
if (started)
throw new LifecycleException("SimpleContext has already started"); // Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
started = true;
try {
// Start our subordinate components, if any
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle) loader).start(); // Start our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).start();
} // Start the Valves in our pipeline (including the basic),
// if any
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);
}
catch (Exception e) {
e.printStackTrace();
} // Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
} public void stop() throws LifecycleException {
if (!started)
throw new LifecycleException("SimpleContext has not been started");
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
try {
// Stop the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).stop();
} // Stop our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).stop();
}
if ((loader != null) && (loader instanceof Lifecycle)) {
((Lifecycle) loader).stop();
}
}
catch (Exception e) {
e.printStackTrace();
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
}
Context容器实例持有对LifecycleSupport lifecycle = new LifecycleSupport(this)的引用,与事件监听器相关方法均为操作该实例的相应方法
在其与生命周期相关方法start()和stop()方法里面,分别调用相关组件的生命周期方法,并采用LifecycleSupport lifecycle引用发布事件
一个简单的监听器实现如下:
public class SimpleContextLifecycleListener implements LifecycleListener { public void lifecycleEvent(LifecycleEvent event) {
Lifecycle lifecycle = event.getLifecycle();
System.out.println("SimpleContextLifecycleListener's event " +
event.getType().toString());
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.");
}
}
}
子容器wrapper实例(SimpleWrapper),同样实现了Lifecycle接口,其相关实现与Context容器类似
public class SimpleWrapper implements Wrapper, Pipeline, Lifecycle { protected LifecycleSupport lifecycle = new LifecycleSupport(this); // implementation of the Lifecycle interface's methods
public void addLifecycleListener(LifecycleListener listener) {
} public LifecycleListener[] findLifecycleListeners() {
return null;
} public void removeLifecycleListener(LifecycleListener listener) {
} public synchronized void start() throws LifecycleException {
System.out.println("Starting Wrapper " + name);
if (started)
throw new LifecycleException("Wrapper already started"); // Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
started = true; // Start our subordinate components, if any
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle) loader).start(); // Start the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start(); // Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
} public void stop() throws LifecycleException {
System.out.println("Stopping wrapper " + name);
// Shut down our servlet instance (if it has been initialized)
try {
instance.destroy();
}
catch (Throwable t) {
}
instance = null;
if (!started)
throw new LifecycleException("Wrapper " + name + " not started");
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false; // Stop the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).stop();
} // Stop our subordinate components, if any
if ((loader != null) && (loader instanceof Lifecycle)) {
((Lifecycle) loader).stop();
} // Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
}
其他相关组件的相关实现不再赘述
---------------------------------------------------------------------------
本系列How Tomcat Works系本人原创
转载请注明出处 博客园 刺猬的温驯
本人邮箱: chenying998179#163.com (#改为@)