Tomcat源码系列(一):生命周期
一、生命周期
像Tomcat这个大的系统,必然需要对生命周期进行统一管理,否则会在整个启动时期显得非常的混乱。幸好Tomcat自己维护了一个非常健全的生命周期管理体系。我们从StandardServer这个最外层容器开始分析,主要分析和生命周期有关的通用类。
2.1 重要类
2.1.1 Lifecycle
public interface Lifecycle {
// 以下是整个生命周期中的13个状态
public static final String BEFORE_INIT_EVENT = "before_init";
public static final String AFTER_INIT_EVENT = "after_init";
public static final String BEFORE_START_EVENT = "before_start";
public static final String START_EVENT = "start";
public static final String AFTER_START_EVENT = "after_start";
public static final String BEFORE_STOP_EVENT = "before_stop";
public static final String STOP_EVENT = "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 static final String PERIODIC_EVENT = "periodic";
public static final String CONFIGURE_START_EVENT = "configure_start";
public static final String CONFIGURE_STOP_EVENT = "configure_stop";
public LifecycleState getState();
public String getStateName();
// 以下是整个整个生命周期里主要执行的四个方法
public void init() throws LifecycleException;
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
public void destroy() throws LifecycleException;
// 对生命周期状态变化监听器的操作
public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
}
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);
}
2.1.2 LifecycleBase
LifecycleBase
直接实现了Lifecycle
,可以看成一个模板方法,他主要对Lifecycle
里面4个生命周期方法进行拓展,增加一些执行拓展方法前的状态判断、控制状态、一场捕获功能。注意这里所说的拓展方法指的是供子类实现的抽象方法,读过一些源码或了解模板设计模式的应该可以理解这样做的好处。
public abstract class LifecycleBase implements Lifecycle {
private static final StringManager sm = StringManager.getManager(LifecycleBase.class);
private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<LifecycleListener>();
private volatile LifecycleState state = LifecycleState.NEW;
private boolean throwOnFailure = true;
@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) {
handleSubClassException(t, "lifecycleBase.initFail", toString());
}
}
// 抽象方法由子类实现
protected abstract void initInternal() throws LifecycleException;
@Override
public final synchronized void start() throws LifecycleException {
// 状态控制:状态判断阶段
if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
LifecycleState.STARTED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
}
return;
}
// 状态控制:状态判断阶段
if (state.equals(LifecycleState.NEW)) {
// 可以看到如果没有进行初始化,就会先执行初始化的方法
init();
} else if (state.equals(LifecycleState.FAILED)) {
stop();
} else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
try {
// 状态控制:状态切换阶段
setStateInternal(LifecycleState.STARTING_PREP, null, false);
// 真正执行启动时的工作
startInternal();
if (state.equals(LifecycleState.FAILED)) {
stop();
} else if (!state.equals(LifecycleState.STARTING)) {
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.startFail", toString());
}
}
// 抽象方法由子类实现
protected abstract void startInternal() throws LifecycleException;
// stop()和destroy()方法,现阶段可以暂时不关注
@Override
public final synchronized void stop() throws LifecycleException {}
protected abstract void stopInternal() throws LifecycleException;
@Override
public final synchronized void destroy() throws LifecycleException {}
protected abstract void destroyInternal() throws LifecycleException;
// 切换生命周期状态方法
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);
}
}
protected void fireLifecycleEvent(String type, Object data) {
// 根据要切换后的状态构造一个状态切换事件
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
}
}
}
2.1.3 MBeanRegistration
这个类是由jmx提供的,里面主要就是对MBean的加载(注册)和卸载(注销)。如果不了解jmx的读者也没有关系,可以跳过这个类,对整体不会产生影响。
public interface MBeanRegistration {
public ObjectName preRegister(MBeanServer server,
ObjectName name) throws java.lang.Exception;
public void postRegister(Boolean registrationDone);
public void preDeregister() throws java.lang.Exception ;
public void postDeregister();
}
2.1.4 JmxEnabled
这个类是Tomcat自己的类,增加了可以增加domain的功能。为Tomcat部署提供了底层几接口。
public interface JmxEnabled extends MBeanRegistration {
String getDomain();
void setDomain(String domain);
ObjectName getObjectName();
}
2.1.5 LifecycleMBeanBase
可以看到LifecycleMBeanBase
虽然实现了LifecycleBase#initInternal()、LifecycleBase#destroyInternal()方法,但是仅仅只是做了一些jmx有关的工作,因此可以猜到其子类依然会覆盖真个方法,后在方法开头加一个super.initInternal()
而已。
可以想象到,为什么LifecycleMBeanBase
只实现了这两个类,因为只有在这两个方法中才适合做jmx相关的工作。
public abstract class LifecycleMBeanBase extends LifecycleBase
implements JmxEnabled {
···忽略一些不重要代码
@Override
protected void initInternal() throws LifecycleException {
if (oname == null) {
mserver = Registry.getRegistry(null, null).getMBeanServer();
oname = register(this, getObjectNameKeyProperties());
}
}
@Override
protected void destroyInternal() throws LifecycleException {
unregister(oname);
}
···忽略一些不重要代码
}
2.1.6 StandardServer
public final class StandardServer extends LifecycleMBeanBase implements Server {
@Override
protected void initInternal() throws LifecycleException {
// 和之前预测的一样,会调用LifecycleMBeanBase#initInternal(),进行Jmx相关工作
super.initInternal();
···忽略一些不重要代码
// 初始化<globalNamingResources/>
globalNamingResources.init();
···忽略一些不重要代码
// 初始化所有<Service/>
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
@Override
protected void startInternal() throws LifecycleException {
// 发布一个CONFIGURE_START_EVENT事件
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
// 启动<globalNamingResources/>
globalNamingResources.start();
// 启动所有<Service/>
synchronized (servicesLock) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
}
// 暂时不关注如下两个方法
@Override
protected void stopInternal() throws LifecycleException {}
@Override
protected void initInternal() throws LifecycleException {}
}
从上可以看到Tomcat的初始化入口其实就是StandardServer#initInternal()
,这么说并不准确,其实是StandardServer#init()
内调用了StandardServer#initInternal()
。它会管理其下所有直接子集
<server>
<globalNamingResources/>
<service/>
<service/>
<server/>