【转】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 ...
随机推荐
- NSDate 获取明天、后天的日期
NSDate * senddate=[NSDate date]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIde ...
- what is php?
PHP is a popular general-purpose scripting language that is especially suited to web development. Fa ...
- DropzoneJS 使用指南
原文链接http://segmentfault.com/a/1190000004045240 官方文档: http://www.dropzonejs.com/ Github: https://gith ...
- 会php不回缓存行吗?多重实现
1.普遍缓存技术: 数据缓存:这里所说的数据缓存是指数据库查询PHP缓存机制,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中 ...
- Networking with PHP
PHP Advanced and Object-Oriented Programming 3rd Edition
- register instruction pointer
Computer Science An Overview _J. Glenn Brookshear _11th Edition We have already encountered the conc ...
- qTip2 精致的jQuery提示信息插件
qTip2 精致的jQuery提示信息插件 出处:http://www.cnblogs.com/lwme/archive/2012/02/16/qtip2-jquery-plugin.html ...
- 文件批量上传的工具,要实现暂停继续、断点续传等功能(使用QtNetwork和QHttpMultiPart,和定时器检查超时)
最近在做一个文件批量上传的工具,要实现暂停继续.断点续传等功能.利用Qt自带的QtNetwork模块,完成这些需求并没有费多少周章,主要思路就是将文件分块,然后用while循环依次传输.具体实现代码比 ...
- Ajax返回中文乱码问题(未解决)
(未解决) 暂时使用办法:改用返回Map<String,String>形式的返回值,在ajax中获取json形式的数据.
- ecshop
if($cat_id == '205'){ $smarty->display('cat1.dwt', $cache_id); }elseif($cat_id == '2'){ $smarty-& ...