tomcat生命周期 - 969251639/study GitHub Wiki
1. Tomcat的生命周期类图:
上面最重要的两个类是LifecycleBase和它的实现类LifecycleMBeanBase,LifecycleBase定义生命周期的基本操作,LifecycleMBeanBase则是操作MBean的类,Lifecycle接口定义了tomcat生命周期的状态和常用的操作方法,LifecycleSupport则提供了操作生命周期的工具类
public interface Lifecycle {
//初始化之前状态
public static final String BEFORE_INIT_EVENT = "before_init";
//初始化之后状态
public static final String AFTER_INIT_EVENT = "after_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 AFTER_DESTROY_EVENT = "after_destroy";
//销毁之前状态
public static final String BEFORE_DESTROY_EVENT = "before_destroy";
//添加到监听器
public void addLifecycleListener(LifecycleListener listener);
//查找所有监听器
public LifecycleListener[] findLifecycleListeners();
//移除监听
public void removeLifecycleListener(LifecycleListener listener);
//初始化方法
public void init() throws LifecycleException;
//开始方法
public void start() throws LifecycleException;
//停止方法
public void stop() throws LifecycleException;
//销毁方法
public void destroy() throws LifecycleException;
//获取当前状态
public LifecycleState getState();
//获取当前状态名
public String getStateName();
}
public final class LifecycleSupport {
// ----------------------------------------------------------- Constructors
//构造方法
public LifecycleSupport(Lifecycle lifecycle) {
super();
this.lifecycle = lifecycle;
}
// ----------------------------------------------------- Instance Variables
private final Lifecycle lifecycle;
//用来保存监听器的集合
private final List<LifecycleListener> listeners = new CopyOnWriteArrayList<>();
// --------------------------------------------------------- Public Methods
//添加到监听器
public void addLifecycleListener(LifecycleListener listener) {
listeners.add(listener);
}
//从查找所有监听器
public LifecycleListener[] findLifecycleListeners() {
return listeners.toArray(new LifecycleListener[0]);
}
//触发所有监听事件
public void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
for (LifecycleListener listener : listeners) {
listener.lifecycleEvent(event);
}
}
//移除监听器
public void removeLifecycleListener(LifecycleListener listener) {
listeners.remove(listener);
}
}
在操作生命周期的方法时,都是通过重写父类的操作来完成,父类只是完成操作前操作后的架子调用,比如下面的init方法(这里的负类是指LifecycleBase)
LifecycleBase:
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
//开始之前
setStateInternal(LifecycleState.INITIALIZING, null, false);
//真正要执行的逻辑
initInternal();
//开始之后
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.initFail",toString()), t);
}
}
//抽象方法,子类重写
protected abstract void initInternal() throws LifecycleException;
StandardServer:
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
// Register global String cache
// Note although the cache is global, if there are multiple Servers
// present in the JVM (may happen when embedding) then the same cache
// will be registered under multiple names
onameStringCache = register(new StringCache(), "type=StringCache");
// Register the MBeanFactory
MBeanFactory factory = new MBeanFactory();
factory.setContainer(this);
onameMBeanFactory = register(factory, "type=MBeanFactory");
// Register the naming resources
globalNamingResources.init();
// Populate the extension validator with JARs from common and shared
// class loaders
if (getCatalina() != null) {
ClassLoader cl = getCatalina().getParentClassLoader();
// Walk the class loader hierarchy. Stop at the system class loader.
// This will add the shared (if present) and common class loaders
while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
if (cl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
try {
File f = new File (url.toURI());
if (f.isFile() &&
f.getName().endsWith(".jar")) {
ExtensionValidator.addSystemResource(f);
}
} catch (URISyntaxException e) {
// Ignore
} catch (IOException e) {
// Ignore
}
}
}
}
cl = cl.getParent();
}
}
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
在父类LifecycleBase中也还有其他的类似行为,比如start,stop等都类似,另外在事件状态变动时都会调用fireLifecycleEvent方法进行事件分发,比如上面的LifecycleBase类中的setStateInternal方法
private synchronized void setStateInternal(LifecycleState state,
Object data, boolean check) throws LifecycleException {
if (log.isDebugEnabled()) {
log.debug(sm.getString("lifecycleBase.setState", this, state));
}
if (check) {
// Must have been triggered by one of the abstract methods (assume
// code in this class is correct)
// null is never a valid state
if (state == null) {
invalidTransition("null");
// Unreachable code - here to stop eclipse complaining about
// a possible NPE further down the method
return;
}
// Any method can transition to failed
// startInternal() permits STARTING_PREP to STARTING
// stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
// STOPPING
if (!(state == LifecycleState.FAILED ||
(this.state == LifecycleState.STARTING_PREP &&
state == LifecycleState.STARTING) ||
(this.state == LifecycleState.STOPPING_PREP &&
state == LifecycleState.STOPPING) ||
(this.state == LifecycleState.FAILED &&
state == LifecycleState.STOPPING))) {
// No other transition permitted
invalidTransition(state.name());
}
}
this.state = state;//变更事件状态
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {//调用所有监听器中的监听该事件的方法
fireLifecycleEvent(lifecycleEvent, data);
}
}
2. Tomcat目前的主要生命周期状态:
NEW:容器刚刚创建时,即在LifecycleBase实例构造完成时的状态。
INITIALIZED:容器初始化完成时的状态。
STARTING_PREP:容器启动前的状态。
STARTING:容器启动过程中的状态。
STARTED:容器启动完成的状态。
STOPPING_PREP:容器停止前的状态。
STOPPING:容器停止过程中的状态。
STOPPED:容器停止完成的状态。
DESTROYED:容器销毁后的状态。
FAILED:容器启动、停止过程中出现异常的状态。
Tomcat的每个容器都会有自身的生命周期,其中也涉及状态的迁移,以及伴随的事件生成,本节详细介绍Tomcat中的容器生命周期实现。所有容器的转态转换(如新疆、初始化、启动、停止等)都是由外到内,由上到下进行,即先执行父容器的状态转换及相关操作,然后再执行子容器的转态转换,这个过程是层层迭代执行的。
3. Tomcat init时序图
4. Tomcat start时序图