【转】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 ...
随机推荐
- MySQL字段之集合(set)枚举(enum)
MySQL字段之集合(set)枚举(enum) (2008-12-23 13:51:23) 标签:it 分类:MySQL 集合 SET mysql> create table jihe(f1 ...
- React.js model
// tutorial1.js var CommentBox = React.createClass({ render: function() { return ( <div className ...
- FW Docker为容器分配指定物理网段的静态IP
官方有关于网桥和IP配置的文档地址:https://docs.docker.com/articles/networking/ 1.宿主机(系统采用ubuntu-14.04.1-server-amd64 ...
- Bash 快捷键大全
快捷键的一些说明: CTRL=C:这个键是指PC键盘上的Ctrl键 ALT=M:这个键是PC键盘上的ALT键,如果你键盘上没有这个键,可以尝试使用ESC键代替 SHIFT=S:此键是PC上的Shift ...
- Redis学习笔记(4)-List
package cn.com; import java.util.List; import redis.clients.jedis.Jedis; import redis.clients.jedis. ...
- 【转】MySQL USE NAMES 'UTF8'
先说MySQL的字符集问题.Windows下可通过修改my.ini内的 # CLIENT SECTION [mysql] default-character-set=utf8 # SERVER SEC ...
- 利用JS脚本通过getAttribute()和setAttribute()等对CSS样式进行操作
HTML中引入CSS样式的方式有三种: 1.最常用的,引入样式表,在样式表中编写样式,引入方式如下:<link href="css/style.css" rel=" ...
- angularJS自定义指令间的“沟通”
由此例子我们可以看出,angularJS使用指令时link的执行顺序<html> <head> <meta charset="utf-8"/> ...
- Java 实现导出excel表 POI
1.首先下载poi-3.6-20091214.jar 2.Student.java import java.util.Date; public class Student { private int ...
- ASP.NET MVC 利用ActionFilterAttribute来做权限等
ActionFilterAttribute是Action过滤类,该属于会在执行一个action之前先执行.而ActionFilterAttribute是 MVC的一个专门处理action过滤的类.基于 ...