生命周期接口
Tomcat拥有很多组件,假如在启动Tomcat时一个一个组件启动,这不仅麻烦而且容易遗漏组件,还会对后面的动态组件扩展带来麻烦。对于这个问题,Tomcat用Lifecycle管理启动、停止、关闭。
Tomcat内部架构中,Server包含Service, Service包含Container和Connector,往下再一层层包含。Tomcat就是以容器的方式来组织整个系统架构的,可以通过父容器启动它的子容器,这样只要启动根容器,即可把其他所有容器都启动,达到统一启动、停止、关闭的效果。
作为统一的接口,Lifecycle把所有的启动、停止、关闭、生命周期相关的方法都组织到一起,就可以很方便地管理Tomcat各个容器组件的生命周期。下面是Lifecycle接口详细的定义。
java">public interface Lifecycle {String BEFORE_INIT_EVENT = "before_init";String AFTER_INIT_EVENT = "after_init";String START_EVENT = "start";String BEFORE_START_EVENT = "before_start";String AFTER_START_EVENT = "after_start";String STOP_EVENT = "stop";String BEFORE_STOP_EVENT = "before_stop";String AFTER_STOP_EVENT = "after_stop";String AFTER_DESTROY_EVENT = "after_destroy";String BEFORE_DESTROY_EVENT = "before_destroy";String PERIODIC_EVENT = "periodic";String CONFIGURE_START_EVENT = "configure_start";String CONFIGURE_STOP_EVENT = "configure_stop";void addLifecycleListener(LifecycleListener listener);LifecycleListener[] findLifecycleListeners();void removeLifecycleListener(LifecycleListener listener);void init() throws LifecycleException;void start() throws LifecycleException;void stop() throws LifecycleException;void destroy() throws LifecycleException;LifecycleState getState();String getStateName();/*** Marker interface used to indicate that the instance should only be used* once. Calling {@link #stop()} on an instance that supports this interface* will automatically call {@link #destroy()} after {@link #stop()}* completes.*/interface SingleUse {}
}
从上面可以看出,Lifecycle其实就定义了一些状态常量和几个方法,例如:init、start、stop等方法,所有需要被生命周期管理的容器都要实现这个接口,并且各自被父容器的相应方法调用。例如,在初始化阶段,根容器Server组件会调用init方法,而在init方法里会调用它的子容器Service组件的init方法,以此类推。
生命周期的转化
Lifecycle有个返回状态的方法getState(),返回的是LifecycleState枚举类型,此枚举包含了生命周期所有的状态,供组件状态之间转换使用。
java">public enum LifecycleState {NEW(false, null),INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),STARTING(true, Lifecycle.START_EVENT),STARTED(true, Lifecycle.AFTER_START_EVENT),STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),STOPPING(false, Lifecycle.STOP_EVENT),STOPPED(false, Lifecycle.AFTER_STOP_EVENT),DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),FAILED(false, null);private final boolean available;private final String lifecycleEvent;LifecycleState(boolean available, String lifecycleEvent) {this.available = available;this.lifecycleEvent = lifecycleEvent;}/*** May the public methods other than property getters/setters and lifecycle* methods be called for a component in this state? It returns* <code>true</code> for any component in any of the following states:* <ul>* <li>{@link #STARTING}</li>* <li>{@link #STARTED}</li>* <li>{@link #STOPPING_PREP}</li>* </ul>** @return <code>true</code> if the component is available for use,* otherwise <code>false</code>*/public boolean isAvailable() {return available;}public String getLifecycleEvent() {return lifecycleEvent;}
}
整个生命周期内状态的转化相对较复杂,转换情况如图:
java"> * start()* -----------------------------* | |* | init() |* NEW -»-- INITIALIZING |* | | | | ------------------«-----------------------* | | |auto | | |* | | \|/ start() \|/ \|/ auto auto stop() |* | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |* | | | | |* | |destroy()| | |* | --»-----«-- ------------------------«-------------------------------- ^* | | | |* | | \|/ auto auto start() |* | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----* | \|/ ^ | ^* | | stop() | | |* | | -------------------------- | |* | | | | |* | | | destroy() destroy() | |* | | FAILED ----»------ DESTROYING ---«----------------- |* | | ^ | |* | | destroy() | |auto |* | --------»----------------- \|/ |* | DESTROYED |* | |* | stop() |* ----»-----------------------------»------------------------------
生命周期事件监听机制
在这么多状态之间转换,我们会有这样的需求:在某个状态发生前后做一些工作。Tomcat使用事件监听器模式来实现这样的功能:
- 事件对象,封装事件的信息,在事件监听器接口的统一方法中作为参数使用,继承java. util.EventObject类
- 事件源,触发事件的源头,不同的事件源会触发不同的事件类型
- 事件监听器,负责监听事件源发出的事件
LifecycleEvent类就是事件对象,继承了EventObject类;LifecycleListener为事件监听器接口,里面只定义了一个方法lifecycleEvent (LifecycleEvent event)。很明显,LifecycleEvent作为这个方法的参数。最后缺一个事件源,一般来说,组件和容器就是事件源。父类LifecycleBase,帮助管理该组件或容器上的监听器,里面维护了一个监听器集合,并提供了注册、移除、触发监听器等方法,这样整个监听器框架就完成了。
事件对象:
java">public final class LifecycleEvent extends EventObject {private static final long serialVersionUID = 1L;/*** Construct a new LifecycleEvent with the specified parameters.** @param lifecycle Component on which this event occurred* @param type Event type (required)* @param data Event data (if any)*/public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {super(lifecycle);this.type = type;this.data = data;}/*** The event data associated with this event.*/private final Object data;/*** The event type this instance represents.*/private final String type;/*** @return the event data of this event.*/public Object getData() {return data;}/*** @return the Lifecycle on which this event occurred.*/public Lifecycle getLifecycle() {return (Lifecycle) getSource();}/*** @return the event type of this event.*/public String getType() {return this.type;}
}
事件监听器接口:
java">public interface LifecycleListener {/*** Acknowledge the occurrence of the specified event.** @param event LifecycleEvent that has occurred*/void lifecycleEvent(LifecycleEvent event);}
事件监听管理类LifecycleBase:
java">public abstract class LifecycleBase implements Lifecycle {/*** The list of registered LifecycleListeners for event notifications.*/private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();@Overridepublic void addLifecycleListener(LifecycleListener listener) {lifecycleListeners.add(listener);}@Overridepublic LifecycleListener[] findLifecycleListeners() {return lifecycleListeners.toArray(new LifecycleListener[0]);}@Overridepublic void removeLifecycleListener(LifecycleListener listener) {lifecycleListeners.remove(listener);}/*** Allow sub classes to fire {@link Lifecycle} events.** @param type Event type* @param data Data associated with event.*/protected void fireLifecycleEvent(String type, Object data) {LifecycleEvent event = new LifecycleEvent(this, type, data);for (LifecycleListener listener : lifecycleListeners) {listener.lifecycleEvent(event);}}protected synchronized void setState(LifecycleState state) throws LifecycleException {setStateInternal(state, null, true);}private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)throws LifecycleException {...this.state = state;String lifecycleEvent = state.getLifecycleEvent();if (lifecycleEvent != null) {fireLifecycleEvent(lifecycleEvent, data);}}
}
事件源,例如StandardSever类,开启的时候,调用setState()方法设置状态,继续调用到LifecycleBase.setStateInternal()方法,最后就会让相关监听器进行处理:
java">public final class StandardServer extends LifecycleMBeanBase implements Server {/*** Global naming resources.*/private NamingResourcesImpl globalNamingResources = null;/*** The naming context listener for this web application.*/private final NamingContextListener namingContextListener;/*** Start nested components ({@link Service}s) and implement the requirements of* {@link org.apache.catalina.util.LifecycleBase#startInternal()}.** @exception LifecycleException if this component detects a fatal error that prevents this component from being* used*/@Overrideprotected void startInternal() throws LifecycleException {...setState(LifecycleState.STARTING);...}
}