通过lifecycle接口控制各个组件的生命周期。
那么它是怎么控制的呢?
看下lifecycle接口定义
lifecycle可以触发的事件如下final定义。
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(LifecycleListenerlistener);
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
}
复制代码
各个组件必须实现start()stop()
方法供父组件调用,从而实现其启动和关闭。 组件注册监听器 监听该组件的事件的发生。
实际使用时simplecontext组件实现lifestyle接口。同时在simplecontext里定义一个变量持有LifecycleSupport
实例。这样就可以用其方法了。 (为什么要实现(自己写实现方法,然后调用LifecycleSupport实例的方法,因为它持有LifecycleSupport对象.)
public class SimpleContext implements Context, Pipeline, Lifecycle {
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
//持有LifecycleSupport对象
复制代码
监听器处理逻辑 启动类增加一个监听器,调用LifecycleSupport方法加入监听器数组。 系统启动时发送事件,将事件传给各个监听器. 可以看出LifecycleSupport是整个过程的中心。看下LifecycleSupport类。 其构造方法持有一个lifecycle实例。
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;
}
}
}
复制代码
public final class Bootstrap {
public static void main(String[] args) {
Connector connector = new HttpConnector();
Wrapper wrapper1 = new SimpleWrapper();//实现了lifecycle接口
wrapper1.setName("Primitive");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new SimpleWrapper();//实现了lifecycle接口
wrapper2.setName("Modern");
wrapper2.setServletClass("ModernServlet");
//SimpleContext实现Lifecycle接口,为什么要实现(自己写实现方法,然后调用LifecycleSupport实例的方法)
Context context = new SimpleContext();//实现了lifecycle接口
context.addChild(wrapper1);
context.addChild(wrapper2);
Mapper mapper = new SimpleContextMapper();
mapper.setProtocol("http");
LifecycleListener listener = new SimpleContextLifecycleListener();
//调simpleContext的addLifecycleListener,内部调用LifecycleSupport的addLifecycleListener。
((Lifecycle) context).addLifecycleListener(listener);
context.addMapper(mapper);
Loader loader = new SimpleLoader();
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
connector.setContainer(context);
try {
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) context).start();
// make the application wait until we press a key.
System.in.read();
((Lifecycle) context).stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
复制代码
start()是如何启动上面实现了Lifecycle接口的组件呢?
首先先检查是否started了,若是,抛异常.
然后利用LifecycleSupport发送fireLifecycleEvent
发送BEFORE_START_EVENT
事件
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);
}
复制代码
然后启动类加载器
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle)loader).start(); //由主容器控制下属组件的启动,启动类加载器
复制代码
因为实现Lifecycle的组件,必须重写start()方法。所以调用相应组件的start()启动组件。
然后遍历启动子容器,调用相应的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();//启动子容器wrapper
}
复制代码
然后启动管道
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start();//启动管道
复制代码
最后发送事件
lifecycle.fireLifecycleEvent(START_EVENT, null);//发送事件
复制代码
至此,有启动类控制的整个流程启动了。(本文只是一个sample,但是思想是相同的)
public synchronized void start() throws LifecycleException {
if (started)
throw new LifecycleException("SimpleContext has already started");
//利用lifecycle = new LifecycleSupport(this)发送事件,在发送方法内调用监听器的方法来处理
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();//启动子容器wrapper
}
// 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);//发送事件
}
复制代码