Tomcat分析二 —— Tomcat的生命周期管理
2 Tocmat的生命周期管理
2.1 Lifecycle 接口
Tomcat通过Lifecycle接口统一管理生命周期,所有有生命周期的组件都要实现Lifecycle接口。它一共做了4件事
定义13个String类型常量,用于LifecycleEvent事件的type属性中,为了区分组件发出的LifecycleEvent事件时的状态(初始化前、启动前、启动中等)。
public interface Lifecycle {String BEFORE_INIT_EVENT = "before_init";String AFTER_INIT_EVENT = "after_init";String START_EVENT = "start";String BEFORE_START_EVENT = "before_start";String AFTER_START_EVENT = "after_start";String STOP_EVENT = "stop";String BEFORE_STOP_EVENT = "before_stop";String AFTER_STOP_EVENT = "after_stop";String AFTER_DESTROY_EVENT = "after_destroy";String BEFORE_DESTROY_EVENT = "before_destroy";String PERIODIC_EVENT = "periodic";String CONFIGURE_START_EVENT = "configure_start";String CONFIGURE_STOP_EVENT = "configure_stop";void addLifecycleListener(LifecycleListener var1);LifecycleListener[] findLifecycleListeners();void removeLifecycleListener(LifecycleListener var1);void init() throws LifecycleException;void start() throws LifecycleException;void stop() throws LifecycleException;void destroy() throws LifecycleException;LifecycleState getState();String getStateName();public interface SingleUse { }
定义三个管理监听器的方法addLifecycleListener、findLifecycleEvent和removeLifecycleListener,分别用来添加、查找和删除LifecycleListener类型的监听器
定义4个生命周期的方法:init、start、stop和destroy,用于执行生命周期的各个阶段的操作
定义了获取当前 状态的两个方法getState和getStateName,用来获取当前的状态,getState获取的事枚举类型,里面列举了生命周期的各个节点,getStateName方法返回String类型的状态的名字,用于JMX中。
2.2 LifecycleBase
Lifecycle默认实现是LifecycleBase,实现了生命周期的组件都直接或间接地继承自LifecycleBase。
- 监听管理使用了LifecycleSupport类来完成,定义了一个LifecycleListener数组类型的属性来保存所有的监听器,然后定义了添加、删除、查找和执行监听器的方法
- 生命周期方法中设置了相应的状态并调用了相应的模版方法,init、start、stop和destroy对应的模版方法分别是initInternal、startInternal、stopInternal和destroyInternal方法,这四个方法由子类具体实现
- 组件当前的状态在声明周期的四个方法中已经设置好了,直接返回
三个管理监听器的方法
private LifecycleSupport lifecycle = new LifecycleSupport(this);@Overridepublic void addLifecycleListener(LifecycleListener listener) {lifecycle.addLifecycleListener(listener);}@Overridepublic LifecycleListener[] findLifecycleListeners() {return lifecycle.findLifecycleListeners();}@Overridepublic void removeLifecycleListener(LifecycleListener listener) {lifecycle.removeLifecycleListener(listener);}
addLifecycleListener、findLifecycleListeners和removeLifecycleListener分别调用了LifecycleSupport中同名的方法,LifecycleSupport监听器是通过一个数组属性listeners保存的
这三个方法就是对listeners(数组类型)属性进行操作
- 添加时新建比当前数组大一的数组,将原来的数据按顺序保存进去,将新的添加最后,并将新建的数组赋给listeners属性
- 删除时先找到要删除的监听器在数组中的序号,新建一个比当前小一的数组,将除了要删除的监听器所在的序号的元素按顺序添加进入,最后再赋值给listeners属性
private LifecycleListener listeners[] = new LifecycleListener[0];
private final Object listenersLock = new Object(); // Lock object for changes to listeners
public void addLifecycleListener(LifecycleListener listener) {synchronized (listenersLock) {LifecycleListener results[] = new LifecycleListener[listeners.length + 1];for (int i = 0; i < listeners.length; i++)results[i] = listeners[i];results[listeners.length] = listener;listeners = results;}
}
public LifecycleListener[] findLifecycleListeners() {return listeners;
}
public void removeLifecycleListener(LifecycleListener listener) {synchronized (listenersLock) {int n = -1;for (int i = 0; i < listeners.length; i++) {if (listeners[i] == listener) {n = i;break;}}if (n < 0)return;LifecycleListener results[] = new LifecycleListener[listeners.length - 1];int j = 0;for (int i = 0; i < listeners.length; i++) {if (i != n)results[j++] = listeners[i];}listeners = results;}
}
LifecycleSupport中还定义了处理LifecycleEvent实践的fireLifecycleEvent方法,按事件的类型(组件的状态)创建了LifecycleEvent事件,然后遍历所有的监听器进行处理。
public void fireLifecycleEvent(String type, Object data) {LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);LifecycleListener interested[] = listeners;for (int i = 0; i < interested.length; i++)interested[i].lifecycleEvent(event);
}
四个生命周期方法
四个声明周期方法的实现首先判断当前的状态和要处理的方法是否匹配,不匹配就会执行相应方法使其匹配(在init之前调用start,start方法里检验状态等,还是会先执行init方法),或不处理甚至抛出异常,如果匹配或者处理后匹配了,会调用相应的模版方法并设置相应的状态。
init方法
LifecycleBase中的状态是通过LifecycleState类型的state属性来保存的,最开始初始化值为NEW,如果不为NEW会调用invalidTransition方法抛出异常,其他三个方法也会这样
public final synchronized void init() throws LifecycleException {//最开始的值必须是NEW,否则会抛出异常if (!state.equals(LifecycleState.NEW)) {invalidTransition(Lifecycle.BEFORE_INIT_EVENT);}try {//初始化前将状态设置为INITALIZINGsetStateInternal(LifecycleState.INITIALIZING, null, false);initInternal();//初始化后将状态设置为INITALIZEDsetStateInternal(LifecycleState.INITIALIZED, null, false);} catch (Throwable t) {ExceptionUtils.handleThrowable(t);setStateInternal(LifecycleState.FAILED, null, false);throw new LifecycleException(sm.getString("lifecycleBase.initFail",toString()), t);}
}
start方法
1. 通过状态检查是否已经启动,已启动则打印日志并直接返回
2. 如果没有初始化则先进性初始化,如果启动失败则关闭,如果状态无法吹了则抛出异常
3. 启动前将状态设置为LifecycleState.STARTING_PREP
4. 调用模版方法启动组件
5. 启动失败将状态设置为FALLED并执行stop方法停止
6. 启动状态不是STARTED则抛出异常
7. 成功启动后将状态设置为STARTED
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);}try {setStateInternal(LifecycleState.STARTING_PREP, null, false);startInternal();if (state.equals(LifecycleState.FAILED)) {stop();} else if (!state.equals(LifecycleState.STARTING)) {invalidTransition(Lifecycle.AFTER_START_EVENT);} else {setStateInternal(LifecycleState.STARTED, null, false);}} catch (Throwable t) {setStateInternal(LifecycleState.FAILED, null, false);}
}
stop方法
1. 通过状态检查是否已经关闭,已关闭则打印日志并直接返回
2. 如果是NEW状态,将当前state设置为STOPPED并返回
3. 如果状态不是STARTED也不是FAILED则抛出异常
4. 如果当前状态是FAILED则将当前标志为BEFORE_STOP_EVENT事件
5. 调用模版方法进行stop
6. 停止状态不是STOPPING和FAILED则抛出异常
7. 成功启动后将状态设置为STOPPED
8. finally里面执行destory方法
public final synchronized void stop() throws LifecycleException {if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||LifecycleState.STOPPED.equals(state)) {if (log.isDebugEnabled()) {} else if (log.isInfoEnabled()) {}return;}if (state.equals(LifecycleState.NEW)) {state = LifecycleState.STOPPED;return;}if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {invalidTransition(Lifecycle.BEFORE_STOP_EVENT);}try {if (state.equals(LifecycleState.FAILED)) {fireLifecycleEvent(BEFORE_STOP_EVENT, null);} else {setStateInternal(LifecycleState.STOPPING_PREP, null, false);}stopInternal();if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {invalidTransition(Lifecycle.AFTER_STOP_EVENT);}setStateInternal(LifecycleState.STOPPED, null, false);} catch (Throwable t) {setStateInternal(LifecycleState.FAILED, null, false);} finally {if (this instanceof Lifecycle.SingleUse) {setStateInternal(LifecycleState.STOPPED, null, false);destroy();}}
}
destory方法
- 如果LifecycleState状态是FAILED则先执行stop方法
- 如果状态是DESTROYING或DESTROYED 记录日志并退出
- 如果状态不是STOPPED、FAILED、NEW、INITIALIZED 抛出异常
- 销毁前将状态设置为LifecycleState.DESTROYING
- 调用模版方法销毁组件
- 销毁后将状态设置为DESTROYED
public final synchronized void destroy() throws LifecycleException {if (LifecycleState.FAILED.equals(state)) {try {stop();} catch (LifecycleException e) {}if (!state.equals(LifecycleState.STOPPED) &&!state.equals(LifecycleState.FAILED) &&!state.equals(LifecycleState.NEW) &&!state.equals(LifecycleState.INITIALIZED)) {invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT);}try {setStateInternal(LifecycleState.DESTROYING, null, false);destroyInternal();setStateInternal(LifecycleState.DESTROYED, null, false);} catch (Throwable t) {setStateInternal(LifecycleState.FAILED, null, false);}
}
setStateInternal()
该方法除了设置状态还检查设置的状态合不合逻辑,并在最后发布相应的事件
private synchronized void setStateInternal(LifecycleState state,Object data, boolean check) throws LifecycleException {if (log.isDebugEnabled()) {log.debug(sm.getString("lifecycleBase.setState", this, state));}if (check) {if (state == null) {invalidTransition("null");return;}if (!(state == LifecycleState.FAILED ||(this.state == LifecycleState.STARTING_PREP &&state == LifecycleState.STARTING) ||(this.state == LifecycleState.STOPPING_PREP &&state == LifecycleState.STOPPING) ||(this.state == LifecycleState.FAILED &&state == LifecycleState.STOPPING))) {invalidTransition(state.name());}}this.state = state;String lifecycleEvent = state.getLifecycleEvent();if (lifecycleEvent != null) {fireLifecycleEvent(lifecycleEvent, data);}
}
fireLifecycleEvent()
处理事件,该方法调用了LifecycleSupport的fireLifecycleEvent方法具体处理
protected void fireLifecycleEvent(String type, Object data) {lifecycle.fireLifecycleEvent(type, data);
}
invalidTransition()
负责抛出指定状态的异常
private void invalidTransition(String type) throws LifecycleException {String msg = sm.getString("lifecycleBase.invalidTransition", type,toString(), state);throw new LifecycleException(msg);
}
两个获取当前状态的方法
在生命周期的相应方法已经将状态设置到了state属性,直接将state返回就可以
public LifecycleState getState() {return state;
}
@Override
public String getStateName() {return getState().toString();
}
Tomcat分析二 —— Tomcat的生命周期管理相关推荐
- 特斯拉自动驾驶汽车事故分析与汽车信息安全生命周期管理
2018年01月22号,特斯拉Model S在公路上撞上了前方的消防车,幸运的是无人伤亡.根据司机描述,当时他在事故中启动了自动驾驶模式.大多数人知道特斯拉可以说是目前世界上最先进的已经具备L2.特定 ...
- 存储知识:数据一致性、分级存储、分层存储与信息生命周期管理
一.概述 数据一致性是指关联数据之间的逻辑关系是否正确和完整.问题可以理解为应用程序自己认为的数据状态与最终写入到磁盘中的数据状态是否一致.比如一个事务操作,实际发出了五个写操作,当系统把前面三个写操 ...
- Tomcat中组件的生命周期管理(三)
本文主要目的是自定义举例分析Catalina内部生命周期管理的运作方式以及拿内部具体源码来具体分析 假设我们有一台电脑由主机(我们用cpu表示)和显示器构成,那么我们要运用上篇文章学到的内容,来管理整 ...
- zuul源码分析之Request生命周期管理
为什么80%的码农都做不了架构师?>>> zuul核心框架 zuul是可以认为是一种API-Gateway.zuul的核心是一系列的filters, 其作用可以类比Servle ...
- Eolink神技之二、API全生命周期管理
Eolink神技之二.API全生命周期管理 目录 Eolink神技之二.API全生命周期管理 Eolink全API全生命周期管理解决的问题 演示过程 一.创建项目文档 1.1.创建项目 1.2.项目管 ...
- Android apk动态加载机制的研究(二):资源加载和activity生命周期管理
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...
- PPT 下载 | 神策数据孙文亮:客户全生命周期管理从方法到实践全解析
在以"场景赋能·驱动有数"为主题的神策 2018 数据驱动大会现场,神策数据技术经理孙文亮发表了名为<客户全生命周期管理从方法到实践>的主题演讲. 温馨提示:点击文末阅 ...
- 谈AK管理之基础篇 - 如何进行访问密钥的全生命周期管理?
简介: 我们也常有听说例如AK被外部攻击者恶意获取,或者员工无心从github泄露的案例,最终导致安全事故或生产事故的发生.AK的应用场景极为广泛,因此做好AK的管理和治理就尤为重要了.本文将通过两种 ...
- 如何发布接口_Devops下的接口全生命周期管理与测试
什么是devops?随着时间的推移,devops的定义也在不断的演进.对于其定义可能出现千人千面,但从核心观点,整体业界还是保持着一致的认识.DevOps不是单一的技术或者工具,甚至不只是一个流程,而 ...
最新文章
- filebeat成精之路
- MVC控制器传递多个实体类集合到视图的方案总结
- 深度学习之卷积神经网络 AlexNet
- KernelShark Documentation
- WinForm里ListBox实现加入项目,并且排序。
- Linux删除文件夹的方法
- ERROR 1201 (HY000) Could not initialize master info structure
- 如何在程序中安装指定apk文件
- Win10 wifi无法上网,连网线却可以正常上网的解决办法
- python正则表达式爬取链家租房信息
- Riverbed宣布收购SD-WAN供应商Ocedo
- 她全奖赴海外读博,一作发Science,毅然回国后任东南大学教授!
- mysql r opt_mysql_ping()以及MYSQL_OPT_RECONNECT
- 基于SSM框架实现的疫情统计系统
- 微信公众号二次开发框架-微擎
- python标准数据类型叮叮叮
- 如何使用if嵌套结构;实现用户输入个人的身高和体重,计算出国际肥胖指标BMI值,并判断输出您属于 哪种体型
- Flutter:Dialog弹窗设置点击空白处不关闭弹窗
- 服务器储存要注意什么
- 五杆机构正运动学公式、逆运动学公式MATLAB代码
热门文章
- SheetJS - XLS sheet_to_json() 方法解析 Excel 时不解析表格标题(表格第一行或N行)
- SnailOS0.03是很傻很天真!
- MySQL之mysql dump的使用
- 热点 可视化 渐变 颜色 java_GIS可视化——热点图
- 高并发环境下热点数据访问的最佳实践。
- mysql cbo rbo_一个sql(cbo,rbo)语句的优化,谢谢
- 浪漫的古桥,是您怡梦的地方
- js学习总结(王红元老师)
- WiFi开发|ESP8266模组SDK开发之SNTP协议
- sqlserver 主键自动生成32位guid