前言
在这一章节中,重点说明LifecycleBase类,前面介绍的Tomcat架构中所涉及到的组件元素,连接器或者容器,或者顶级节点Server,都继承了LifecycleBase类。
需要注意的是,LifecycleBase类里大量用到了模板模式,其中有四个抽象方法,initInternal(),startInternal(),stopInternal(),destroyInternal(),用来给组件进行实现,进行自定义的初始化,启动,停止,销毁动作。
类图
状态
生命周期有以下几个状态【参照LifecycleState类】:
NEW :组件实例化之后的默认状态
INITIALIZING:初始化
INITIALIZED :已初始化
STARTING_PREP:启动前置
STARTING :启动中
STARTED :已启动
STOPPING_PREP:停止前置
STOPPING :停止中
STOPPED :已停止
DESTROYING :销毁中
DESTROYED :已销毁
FAILED :失败
下面一一说明这些状态
新建
对应状态:NEW
组件的默认状态,新建实例成功之后,就是此状态。
如果组件准备初始化时,不是此状态,则抛出生命周期异常【LifecycleException】,无效的状态转变。
初始化
对应状态:INITIALIZING & INITIALIZED
可以看到,init()方法使用了模板模式,不仅这个方法,后续介绍到的start(),stop(),destroy()方法,都使用了模板模式。
调用初始化方法时,会进行这两个状态的切换,注意initInternal()方法,这是一个抽象方法,用来给其他组件实现,执行自身真正的初始化
public final synchronized void init() throws LifecycleException {
... 忽略一些前置检查代码
// 切换状态到初始化中
setStateInternal(LifecycleState.INITIALIZING, null, false);
// 其他组件实现,比如StandardServer等
initInternal();
// // 切换状态到已经初始化
setStateInternal(LifecycleState.INITIALIZED, null, false);
}
启动
对应状态:STARTING_PREP & STARTING & STARTED
源代码中可以看出,组件的启动有可能失败,如果失败,那么就停止后续的过程,直接执行停止动作
public final synchronized void start() throws LifecycleException {
... 忽略一些前置检查代码
// 状态切换为启动前置
setStateInternal(LifecycleState.STARTING_PREP, null, false);
// 抽象方法,组件实现,切换状态到STARTING。可以看看最后FAILED状态切换的介绍,里面展示了StandardContext类startInternal()方法的部分实现
startInternal();
// 如果在组件启动过程中出现了错误,则将状态切换为FAILED
if (state.equals(LifecycleState.FAILED)) {
// 执行LifecycleBase.stop()
stop();
} else {
// 状态切换为已经启动
setStateInternal(LifecycleState.STARTED, null, false);
}
}
失败
对应状态:FAILED
一般只有应用【StandardContext组件】启动出现了问题,才会将组件状态切换到FAILED,这里我们看看StandardContext的startInternal()方法
@Override
protected synchronized void startInternal() throws LifecycleException {
... 忽略StandardContext的启动代码
// Reinitializing if something went wrong
if (!ok) {
// 如果启动过程中,有任何一个资源或者配置或者依赖没有执行成功,都会被认定为失败
setState(LifecycleState.FAILED);
} else {
// 如果启动成功,切换状态到启动中
setState(LifecycleState.STARTING);
}
}
停止
对应状态:STOPPING_PREP & STOPPING & STOPPED
stop方法内,如果接受到了FAILED状态,对其进行特殊处理,不要过渡到STOPPING_PREP状态,那样会短暂地将该组件标记为可用,但请确保已触发BEFORE_STOP_EVENT,这里BEFORE_STOP_EVENT代表的就是STOPPING_PREP状态,详情可见LifecycleState.STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT)。
public final synchronized void stop() throws LifecycleException {
... 忽略一些前置检查代码
if (state.equals(LifecycleState.FAILED)) {
// 不要过渡到STOPPING_PREP状态,那样会短暂地将该组件标记为可用,但请确保已触发BEFORE_STOP_EVENT,这里BEFORE_STOP_EVENT代表的就是STOPPING_PREP状态,详情可见LifecycleState.STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT)
fireLifecycleEvent(BEFORE_STOP_EVENT, null);
} else {
// 组件状态切换到停止前置
setStateInternal(LifecycleState.STOPPING_PREP, null, false);
}
// 执行组件实现类的停止方法,切换状态到STOPPING
stopInternal();
// 组件状态切换到已停止
setStateInternal(LifecycleState.STOPPED, null, false);
}
销毁
对应状态:DESTROYING & DESTROYED
需要注意的是,销毁方法中也可能收到FAILED状态,如果是FAILED,则转回到stop方法中进行处理。
public final synchronized void destroy() throws LifecycleException {
// 如果是FAILED状态,则特殊处理
if (LifecycleState.FAILED.equals(state)) {
// Triggers clean-up
stop();
}
... 忽略一些前置检查代码
// 切换到销毁中状态
setStateInternal(LifecycleState.DESTROYING, null, false);
// 执行组件具体的销毁方法
destroyInternal();
// 切换到已销毁状态
setStateInternal(LifecycleState.DESTROYED, null, false);
}