Catalina由很多组件组成,当Catalina启动时,所有组件都需要启用;当Catalina停止时,所有组件也需要停止并在停止之前完成清理工作。比如,当我们停止一个容器时,必须调用所有已加载的servlet的destroy方法,同时会话管理器也需要将session对象存储到辅助存储器中。通过org.apache.catalina.Lifecycle接口可以实现一个启动和停止组件的一致性机制。
一个实现了LifeCycle的组件会触发以下事BEFORE_START_EVENT, START_EVENT, AFTER_START_EVENT,BEFORE_STOP_EVENT, STOP_EVENT, 和 AFTER_STOP_EVENT。前面三个事件一般是在组件启动时触发,后三个是在组件停止时触发。
Lifecycle接口
Catalina在设计上允许一个组件下包含多个子组件。比如,一个容器内可以有Loader,Manager等这些组件。一父组件负责其所有子组件的启动和停止。。Catalina的设计成所有的组件被一个父组件来管理,这样的话bootstrap类只需要启动一个组件就可以了,其它的子组件由这个组件负责启动或是停止。
package org.apache.catalina;
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;
}
以上是Lifecycle接口内容。其中最重要的方法是start和stop。一个组件为这两个方法提供实现,这样其父组件就可以通过这两个方法来启动或是停用它们。
LifecycleEvent类
Catalina中生命周期事件由org.apache.catalina.LifecycleEvent类来表示。
package org.apache.catalina;
import java.util.EventObject;
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);
}
}
LifecycleListener类
监听器由org.apache.catalina.LifecycleListener接口来表示,这个接口只有一个方法。
package org.apache.catalina;
import java.util.EventObject;
public interface LifecycleListener {
public void lifecycleEvent(LifecycleEvent event);
}
LifecycleSupport类
一个实现了Lifecycle接口的组件如果允许监听器注册其感兴趣的事件,那么这个组件则必须为Lifecycle中与监听器相关的三个方法提供实现:addLifecycleListener, findLifecycleListeners, 和removeLifecycleListener。那么这个组件中就会用一个ArrayList或是其它类似的类来保存对它感兴趣的监听器。
Catalina提供了一个工具类来方便组件处理监听器和派发事件,这个类就是org.apache.catalina.util.LifecycleSupport。
package org.apache.catalina.util;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
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;
}
}
}
从上面的代码可以看出,LifecycleSupport类将所有生命周期监听器都保存在一个名为listeners的数组中,这个数据初始化长度为0。
private LifecycleListener listeners[] = new LifecycleListener[0];
当调用addLifecycleListener方法新增一个监听器时,新建一个长度比原来listeners长度大1的数组,然后把旧数组中所有数据都拷贝新数组中并把新增的监听器添加到新数组的末尾。当调用removeLifecycleListener方法删除一个监听器,类似地,生成一个比原来长度小1的数组,将原数组中除被删除的监听器以外都拷贝到新数组中。当然所有的新数组最后都赋值给listeners.
fireLifecycleEvent方法用来派发一个生命周期事件。首先,方法克隆了listeners数组;然后,它遍历所有注册的监听器,并调用它们的fireLifecycleEvent方法传递触发事件。
一个实现了Lifecycle的组件可以使用LifecycleSupport类。举例来说,在本章的SimpleContext类中,声明了一个成员变量:
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
如果是增加一个生命周期的监听,SimpleContext类会直接调用LifecycleSupport类的addLifecycleListener方法。
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
还有删除监听器或是派发事件,调用的也都是LifecycleSupport类中的方法。