1 概述
Catalina包括很多组件,当catalina启动的时候,也需要启动这些组件,当关闭catalina的时候同时也需要关闭这些组件。Tomcat通过事件机制来实现这种控制,所有的组件都实现org.apache.catalina.Lifecycle接口。
例如,当container关闭时,它必须调用已经载入的servlet的destroy方法。tomcat中的实现机制是通过实现org.apache.catalina.Lifecycle接口来管理。
实现了org.apache.catalina.Lifecycle接口的组件会触发下面的事件:
BEFORE_START_EVENT;
START_EVENT;
AFTER_START_EVENT;
BEFORE_STOP_EVENT;
STOP_EVENT;
AFTER_STOP_EVENT。
当组件启动是会触发前三个事件(BEFORE_START_EVENT,START_EVENT,AFTER_START_EVENT),关闭组件时会触发后三个事件(BEFORE_STOP_EVENT,STOP_EVENT,AFTER_STOP_EVENT)。而相应的监听器由org.apache.catalina.LifecycleListener接口表示。
本章将讨论三种类型,Lifecycle接口、LifecycleListener接口、LifecycleEvent类、LifecycleSupport类。
2 Lifecycle接口
catalina在设计上允许一个组件包含其他组件,如container中可以包含loader,manger等组件。
父组件负责启动/关闭其包含的子组件。所有的组件都可以通过其父组件来启动/关闭,这种单一启动/关闭机制是通过Lifecycle接口实现的。Lifecycle接口定义如下:
package org.apache.catalina; public interface Lifecycle { public static final String INIT_EVENT = "init"; 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 static final String DESTROY_EVENT = "destroy"; 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方法。父组件通过这两个方法来启动/关闭该组件。addLifecycleListener,findLifecycleListeners,removeLifecycleListener三个方法用于向组件注册/查找/删除监听器。当事件发生时,会触发监听器。接口中还定义了相关事件。
3. LifecycleListener接口
接口定义如下:
//当监听的事件发生时,触发LifecycleListener接口的lifecycleEvent方法 package org.apache.catalina; public interface LifecycleListener { //具体实现放在各组件对应的LifecycleListener中 public void lifecycleEvent(LifecycleEvent event); }
其中,当监听的事件发生时,触发lifecycleEvent方法。
4. LifecycleEvent类
org.apache.catalina.LifecycleEvent类表示生命周期中的某个事件。定义如下:
//LifecycleEvent类表示生命周期中的某个事件 package org.apache.catalina; public final class LifecycleEvent { //type即为各状态init、start。。。 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); } }
5 LifecycleSupport类
实现了Lifecycle接口的组件可以向监听器注册感兴趣的事件,catalina提供一个工具类来管理对组件注册的监听器,org.apache.catalina.util.LifecycleSupport。代码如下:
LifecycleSupport类中用数组类型的变量listeners存储了所有监听器。当添加一个新的监听器时,是创建一个新数组,存储全部的监听器。删除一个监听器的时候,也是返回一个新的数组对象。
fireLifecycleEvent方法会触发已经注册的各个监听器。
实现了Lifecycle接口的组件可以使用LifecycleSupport类,对监听器进行添加、删除、触发等操作。
//catalina提供一个工具类来管理对组件注册的监听器LifecycleSupport,实现了Lifecycle接口的组件可以向监听器注册感兴趣的事件, /** * LifecycleSupport类中用数组类型的变量listeners存储了所有监听器。 * 当添加一个新的监听器时,是创建一个新数组,存储全部的监听器。删除一个监听器的时候,也是返回一个新的数组对象。 * fireLifecycleEvent方法会触发已经注册的各个监听器。 */ 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]; private final Object listenersLock = new Object(); // Lock object for changes to listeners private String state = "NEW"; public void addLifecycleListener(LifecycleListener listener) { synchronized (listenersLock) { 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) { if (Lifecycle.INIT_EVENT.equals(type)) { state = "INITIALIZED"; } else if (Lifecycle.BEFORE_START_EVENT.equals(type)) { state = "STARTING_PREP"; } else if (Lifecycle.START_EVENT.equals(type)) { state = "STARTING"; } else if (Lifecycle.AFTER_START_EVENT.equals(type)) { state = "STARTED"; } else if (Lifecycle.BEFORE_STOP_EVENT.equals(type)) { state = "STOPPING_PREP"; } else if (Lifecycle.STOP_EVENT.equals(type)) { state = "STOPPING"; } else if (Lifecycle.AFTER_STOP_EVENT.equals(type)) { state = "STOPPED"; } else if (Lifecycle.DESTROY_EVENT.equals(type)) { state = "DESTROYED"; } //通过type判断哪个状态 LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = listeners; for (int i = 0; i < interested.length; i++) interested[i].lifecycleEvent(event); } public void removeLifecycleListener(LifecycleListener listener) { synchronized (listenersLock) { 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 String getState() { return state; } }
具体组件使用:
Catalina包括很多组件,当catalina启动的时候,也需要启动这些组件,当关闭catalina的时候同时也需要关闭这些组件。Tomcat通过事件机制来实现这种控制,所有的组件都实现org.apache.catalina.Lifecycle接口。
//注意组件实现了Lifecycle接口 public final class StandardServer implements Lifecycle { //catalina提供一个工具类来管理对组件注册的监听器LifecycleSupport,实现了Lifecycle接口的组件可以向监听器注册感兴趣的事件, private LifecycleSupport lifecycle = new LifecycleSupport(this); private NamingContextListener namingContextListener = null; private Service services[] = new Service[0]; /** * 构造方法中添加对应的监听器LifecycleListener */ public StandardServer() { super(); ServerFactory.setServer(this); globalNamingResources = new NamingResources(); globalNamingResources.setContainer(this); if (isUseNaming()) { if (namingContextListener == null) { namingContextListener = new NamingContextListener(); addLifecycleListener(namingContextListener); } } } //LifecycleSupport工具类添加对应的监听器LifecycleListener /** * LifecycleSupport将该StandardServer对应的监听器NamingContextListener放入其内的LifecycleListener listeners[]数组中 * * public void addLifecycleListener(LifecycleListener listener) { * * synchronized (listenersLock) { * 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 void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } //组件初始化 public void initialize() { if (initialized) { log.info(sm.getString("standardServer.initialize.initialized")); return; } lifecycle.fireLifecycleEvent(INIT_EVENT, null); initialized = true; ...... // Initialize our defined Services for (int i = 0; i < services.length; i++) { services[i].initialize(); } } //组件启动 public void start() throws LifecycleException { if (started) { log.debug(sm.getString("standardServer.start.started")); return; } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; // 启动子组件Services synchronized (services) { for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).start(); } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); } //组件关闭 public void stop() throws LifecycleException { // Validate and update our current component state if (!started) return; // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Stop our defined Services for (int i = 0; i < services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).stop(); } lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); stopAwait(); } /** * 添加子组件 */ public void addService(Service service) { service.setServer(this); synchronized (services) { Service results[] = new Service[services.length + 1]; System.arraycopy(services, 0, results, 0, services.length); results[services.length] = service; services = results; if (initialized) { try { service.initialize(); } catch (LifecycleException e) { log.error(e); } } if (started && (service instanceof Lifecycle)) { try { ((Lifecycle) service).start(); } catch (LifecycleException e) { ; } } // Report this property change to interested listeners support.firePropertyChange("service", null, service); } } 。。。 }
public class NamingContextListener implements LifecycleListener { public void lifecycleEvent(LifecycleEvent event) { //具体实现方法 ... if (event.getType() == Lifecycle.START_EVENT) { } else if (event.getType() == Lifecycle.STOP_EVENT) { } } }
参考:《深入剖析Tomcat 》第6章 生命周期(Lifecycle)
tomcat 7 源码分析-8 生命周期lifecycle和监听listener
Tomcat自定义LifecycleListener,如何监听StandardContext