水煮Tomcat(三) – 生命の周期

91 阅读3分钟

前言

在这一章节中,重点说明LifecycleBase类,前面介绍的Tomcat架构中所涉及到的组件元素,连接器或者容器,或者顶级节点Server,都继承了LifecycleBase类。
需要注意的是,LifecycleBase类里大量用到了模板模式,其中有四个抽象方法,initInternal(),startInternal(),stopInternal(),destroyInternal(),用来给组件进行实现,进行自定义的初始化,启动,停止,销毁动作。

类图

image.png

状态

生命周期有以下几个状态【参照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);
}