【转】Tomcat组件生命周期管理
Tomcat组件生命周期管理
Tomcat中Server,Service,Connector,Engine,Host,Context,它们都实现了org.apache.catalina.Lifecycle接口,而org.apache.catalina.util.LifecycleBase采用了模板方法模式来对所有支持生命周期管理的组件的生命周期各个阶段进行了总体管理,每个需要生命周期管理的组件只需要继承这个基类,然后覆盖对应的钩子方法即可完成相应的生命周期阶段性的管理工作。 下面我们首先来看看org.apache.catalina.Lifecycle接口的定义,它的类图如下图所示:
从上图我们可以清楚的看到LifeCycle中主要有四个生命周期阶段,它们分别是init(初始化),start(启动),stop(停止),destory(销毁)。知道了这四个生命周期阶段以后,咋们就来看看org.apache.catalina.util.LifecycleBase是如何实现模板方法模式的。 那接下来我们就来看看org.apache.catalina.util.LifecycleBase类的定义,它的类图如下所示:
上图中用红色标注的四个方法就是模板方法模式中的钩子方法,子类可以通过实现钩子方法来纳入到基类已经流程化好的生命周期管理中。
上面我们对LifeCycle和LifeCycleBase有了一个总体的认识,接下来,我们通过查看org.apache.catalina.util.LifecycleBase的源代码来具体的分析一下。 咋们首先来看org.apache.catalina.util.LifecycleBase的init方法的实现。
org.apache.catalina.util.LifecycleBase#init
@Override
public final synchronized void init() throws LifecycleException {
//
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
setStateInternal(LifecycleState.INITIALIZING, null, false); try {
// 2 钩子
initInternal();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.initFail",toString()), t);
}
// 3
setStateInternal(LifecycleState.INITIALIZED, null, false);
}
下面我们逐一来分析一下上述代码中标注了数字的地方:
- 标注1的代码首先检测当前组件的状态是不是
NEW(新建),如果不是就调用org.apache.catalina.util.LifecycleBase#invalidTransition方法来将当前的状态转换过程终止,而invalidTransition的实现是抛出了org.apache.catalina.LifecycleException异常。接着调用了setStateInternal方法将状态设置为INITIALIZING(正在初始化) - 标注2的代码就是init模板方法的钩子,子类可以通过实现
protected abstract void initInternal() throws LifecycleException;方法来纳入初始化的流程。 - 标注3的代码将组件的状态改为
INITIALIZED(已初始化)。
上面我们分析了init模板方法,接下来我们再看看start方法具体做了什么事情。start的代码如下:
org.apache.catalina.util.LifecycleBase#start
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);
}
//
setStateInternal(LifecycleState.STARTING_PREP, null, false);
try {
//4 钩子
startInternal();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.startFail",toString()), t);
}
//
if (state.equals(LifecycleState.FAILED) ||
state.equals(LifecycleState.MUST_STOP)) {
stop();
} else {
// Shouldn't be necessary but acts as a check that sub-classes are
// doing what they are supposed to.
if (!state.equals(LifecycleState.STARTING)) {
invalidTransition(Lifecycle.AFTER_START_EVENT);
}
setStateInternal(LifecycleState.STARTED, null, false);
}
}
下面我们逐一来分析一下上述代码中标注了数字的地方:
- 标注1的代码检测当前组件的状态是不是
STARTING_PREP(准备启动),STARTING(正在启动),STARTED(已启动).如果是这三个状态中的任何一个,则抛出LifecycleException。 - 标注2的代码的检查其实主要是为了保证组件状态的完整性,在正常启动的流程中,应该是不会出现没有初始化就启动,或者还没启动就已经失败的情况。
- 标注3的代码设置组件的状态为
STARTING_PREP(准备启动状态) - 标注4的代码是start模板方法的钩子方法,子类通过实现
org.apache.catalina.util.LifecycleBase#startInternal这个方法来纳入到组件启动的流程中来。 - 标注5的代码做了一些状态检查,然后最终将组件的状态设置为
STARTED(已启动)
上面我们分析了init和start方法的流程,对于stop和destroy方法的总体过程是类似的,大家可以自己阅读一下,但是通过上面的分析,我们可以得出生命周期方法的总体的骨架,如果用伪代码来表示可以简化为如下:
org.apache.catalina.util.LifecycleBase#lifeCycleMethod
public final synchronized void lfieCycleMethod() throws LifecycleException {
stateCheck();//状态检查
//设置为进入相应的生命周期之前的状态
setStateInternal(LifecycleState.BEFORE_STATE, null, false);
lfieCycleMethodInternal();//钩子方法
//进入相应的生命周期之后的状态
setStateInternal(LifecycleState.AFTER_STATE, null, false);
}
Reference:
【转】Tomcat组件生命周期管理的更多相关文章
- Castle IOC容器组件生命周期管理
主要内容 1.生命处理方式 2.自定义生命处理方式 3.生命周期处理 一.生命处理方式 我们通常创建一个组件的实例使用new关键字,这样每次创建出来的都是一个新的实例,如果想要组件只有一个实例,我们会 ...
- Tomcat中组件的生命周期管理公共接口Lifecycle
Tomcat的组件都会实现一个Lifecycle接口,以方便组件的生命周期的统一管理 interface Lifecycle 组件生命周期中主要的几个方法 增加监听器,事件委托机制 public vo ...
- TOMCAT源码分析——生命周期管理
前言 从server.xml文件解析出来的各个对象都是容器,比如:Server.Service.Connector等.这些容器都具有新建.初始化完成.启动.停止.失败.销毁等状态.tomcat的实现提 ...
- Salesforce 应用生命周期管理
应用程序生命周期管理 一个Salesforce系统可以有多个版本,最常见的有: production版本:终端用户实际使用的版本 sandbox版本:沙盒环境,用于开发.测试等 在对Salesforc ...
- 004-docker命令-容器生命周期管理、容器操作
1.容器生命周期管理 docker run :创建一个新的容器并运行一个命令 语法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...] OPTIONS说明: - ...
- Android之Android apk动态加载机制的研究(二):资源加载和activity生命周期管理
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...
- JavaWeb各大组件生命周期
JavaWeb各大组件生命周期 servlet生命周期 服务器打开:在第一次请求时实例化与初始化:然后进行服务:最后服务器关闭销毁 Cookie生命周期:存储在客户端 如果不设置过期时间,则表示这个c ...
- Jasper:用户指南 / 设备 / 生命周期管理 / SIM 卡状态
ylbtech-Jasper:用户指南 / 设备 / 生命周期管理 / SIM 卡状态 1.返回顶部 1. SIM 卡状态 每个设备都有一个状态,决定了它能否在网络上建立数据连接,并且会影响设备是否计 ...
- Android应用常规开发技巧——善用组件生命周期
数据管理 对于仅仅读数据.一种经常使用的管理模式是在onCreate函数中进行数据的载入,直到组件的onDestory函数被调用时在进行释放. // 缓存仅仅读的数据 private Object r ...
随机推荐
- linux下svn的co如何排除目录
某些原因想在svn co的时候排除某些目录,可以绕个圈子,分三步来完成: co外层目录: svn checkout --depth empty $URL [$LOCATION] 完成之后,会有一个只包 ...
- 5.PHP内核探索:多进程/线程的SAPI生命周期
多进程的SAPI生命周期 通常PHP是编译为apache的一个模块来处理PHP请求.Apache一般会采用多进程模式, Apache启动后会fork出多个子进程,每个进程的内存空间独立,每个子进程都会 ...
- 1.PHP内核探索:从SAPI接口开始
SAPI:Server Application Programming Interface 服务器端应用编程端口.研究过PHP架构的同学应该知道这个东东的重要性,它提供了一个接口,使得PHP可以和其他 ...
- 【转】CodeIgniter定义自己的Helper和Helper的方法
最近做程序,采用了PHP+CodeIgniter框架,总体来说这框架很轻而且上手也很快的. 首先,说下如何定义自己的Helper,个人理解helper其实就是定义函数方法. 如果要建个全新的自己的He ...
- bpel 之伙伴
一.伙伴链接类型(Partner Link Types) 1.交互过程 伙伴之间的交互过程共分为两种典型情况: 流程调用伙伴后同步等待返回结果.这种情况通常是伙伴能很快返回结果,流程不需要等待很长时间 ...
- HTML5 本地存储 LocalStorage
说到本地存储,这玩意真是历尽千辛万苦才走到HTML5这一步,之前的历史大概如下图所示: 最早的Cookies自然是大家都知道,问题主要就是太小,大概也就4KB的样子,而且IE6只支持每个域名20个co ...
- maven--composer---setting.xml(updatepolicy)---mvn install , mvn deploy
场景:最近再整系统的自动部署流程,由于公司的jar包在svn以及mvn的仓库上都存在,开发人员在开发的过程中都依赖mvn仓库中的Jar 包,在jar上线的时候,配置管理人员把jar 从svn管理的工作 ...
- js判断图片是否存在,并做处理
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- php+mysql实现事务回滚
模拟条件:第一个表插入成功,但是第二个表插入失败,回滚.第一个表插入成功,第二个表插入成功,执行.第一个表插入失败,第二个表插入成功,回滚.第一个表插入失败,第二个表插入失败,回滚.以上情况都需要回滚 ...
- There is no tracking information for the current branch
There is no tracking information for the current branch. Please specify which branch you want to mer ...