浅读tomcat架构设计之tomcat生命周期(2)
浅读tomcat架构设计和tomcat启动过程(1)
https://www.cnblogs.com/piaomiaohongchen/p/14977272.html
tomcat通过org.apache.catalina.Lifecycle接口统一管理生命周期,所有有生命周期的组建都要实现Lifecycle接口.
通过反射加载查看代码:
Lifecycle的接口方法有很多,简单解读下:
(1)定义13个String类型的常量,不同的常量,代表不同的状态信息

(2)定义了3个管理监听器的方法:
分别是添加,监听和删除
void addLifecycleListener(LifecycleListener var1);
LifecycleListener[] findLifecycleListeners();
void removeLifecycleListener(LifecycleListener var1);

(3)定义了四个生命周期方法:
分别是初始化,开启,停止,销毁:
void init() throws LifecycleException; void start() throws LifecycleException; void stop() throws LifecycleException; void destroy() throws LifecycleException;

(4)定义了获取状态的两个方法:
LifecycleState getState(); String getStateName();

其中getState的返回类是enum类型,getStateName返回的类型是String类型
Lifecycle接口的默认实现是org.apache.catalina.util.LifecycleBase,LifecycleBase为Lifecycle里的接口方法提供了默认实现.
先看看三个管理监听器方法的具体实现:
org.apache.catalina.util.LifecycleBase:
public void addLifecycleListener(LifecycleListener listener) {
this.lifecycle.addLifecycleListener(listener);
}
public LifecycleListener[] findLifecycleListeners() {
return this.lifecycle.findLifecycleListeners();
}
public void removeLifecycleListener(LifecycleListener listener) {
this.lifecycle.removeLifecycleListener(listener);
}
发现在方法内部都是调用的lifecycle.**()方法
而this.lifecycle的定义是
private final LifecycleSupport lifecycle = new LifecycleSupport(this);

三个监听器方法都是调用的是LifecycleSupport类的对象方法
LifecycleSupport监听器是通过一个数组属性listeners来保存的,代码如下:
org.apache.catalina.util.LifecycleSupport:
private final Object listenersLock = new Object();
public LifecycleSupport(Lifecycle lifecycle) {
this.lifecycle = lifecycle;
}
public void addLifecycleListener(LifecycleListener listener) {
synchronized(this.listenersLock) {
LifecycleListener[] results = new LifecycleListener[this.listeners.length + 1];
for(int i = 0; i < this.listeners.length; ++i) {
results[i] = this.listeners[i];
}
results[this.listeners.length] = listener;
this.listeners = results;
}
}
public LifecycleListener[] findLifecycleListeners() {
return this.listeners;
}
public void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this.lifecycle, type, data);
LifecycleListener[] interested = this.listeners;
for(int i = 0; i < interested.length; ++i) {
interested[i].lifecycleEvent(event);
}
}
public void removeLifecycleListener(LifecycleListener listener) {
synchronized(this.listenersLock) {
int n = -1;
for(int i = 0; i < this.listeners.length; ++i) {
if (this.listeners[i] == listener) {
n = i;
break;
}
}
if (n >= 0) {
LifecycleListener[] results = new LifecycleListener[this.listeners.length - 1];
int j = 0;
for(int i = 0; i < this.listeners.length; ++i) {
if (i != n) {
results[j++] = this.listeners[i];
}
}
this.listeners = results;
}
}
}
这三个方法的实现非常简单,就是新增/删除/查找等动作的实现,就是对listener属性做操作
其中的fireLifecycleEvent函数的含义是用于遍历所有监听器进行处理

四个生命周期的方法:
先看init方法,让我们回到之前的org.apache.catalina.util.LifecycleBase类:
org.apache.catalina.util.LifecycleBase:
public final synchronized void init() throws LifecycleException {
if (!this.state.equals(LifecycleState.NEW)) {
this.invalidTransition("before_init");
}
this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false);
try {
this.initInternal();
} catch (Throwable var2) {
ExceptionUtils.handleThrowable(var2);
this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[]{this.toString()}), var2);
}
this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false);
}
代码很简单,就是先判断state是否是LifecycleState.NEW,如果是NEW的话就设置为state状态为LifecycleState.INITIALIZING,如果不是,就抛出异常,所以init初始化的时候必须是LifecycleState.NEW
接着往下看,看start方法:
public final synchronized void start() throws LifecycleException {
if (!LifecycleState.STARTING_PREP.equals(this.state) && !LifecycleState.STARTING.equals(this.state) && !LifecycleState.STARTED.equals(this.state)) {
if (this.state.equals(LifecycleState.NEW)) {
this.init();
} else if (this.state.equals(LifecycleState.FAILED)) {
this.stop();
} else if (!this.state.equals(LifecycleState.INITIALIZED) && !this.state.equals(LifecycleState.STOPPED)) {
this.invalidTransition("before_start");
}
this.setStateInternal(LifecycleState.STARTING_PREP, (Object)null, false);
try {
this.startInternal();
} catch (Throwable var2) {
ExceptionUtils.handleThrowable(var2);
this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
throw new LifecycleException(sm.getString("lifecycleBase.startFail", new Object[]{this.toString()}), var2);
}
if (!this.state.equals(LifecycleState.FAILED) && !this.state.equals(LifecycleState.MUST_STOP)) {
if (!this.state.equals(LifecycleState.STARTING)) {
this.invalidTransition("after_start");
}
this.setStateInternal(LifecycleState.STARTED, (Object)null, false);
} else {
this.stop();
}
} else {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStarted", new Object[]{this.toString()}), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStarted", new Object[]{this.toString()}));
}
}
}
start方法做的事情比int方法多一些,判断state状态,如果是LifecycleState.NEW,就初始化,根据不同的state状态,进不同的逻辑,然后设置状态调用setStateInternal方法:
跟进方法:
还是在org.apache.catalina.util.LifecycleBase:
private synchronized void setStateInternal(LifecycleState state, Object data, boolean check) throws LifecycleException {
if (log.isDebugEnabled()) {
log.debug(sm.getString("lifecycleBase.setState", new Object[]{this, state}));
}
if (check) {
if (state == null) {
this.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)) {
this.invalidTransition(state.name());
}
}
this.state = state;
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {
this.fireLifecycleEvent(lifecycleEvent, data);
}
}
这个方法先是判断check,然后判断state是否为null,是null就抛出异常,最后将state赋值给state变量,然后调用getLifecycleEvent方法处理事件,下面的this.fireLifecycleEvent(lifecycleEvent, data);实际上调用的是LifecycleSupport类的方法:
跟进这个方法看下:
protected void fireLifecycleEvent(String type, Object data) {
this.lifecycle.fireLifecycleEvent(type, data);
}
继续往上回溯:
private final LifecycleSupport lifecycle = new LifecycleSupport(this);
同理stop和destroy方法逻辑类似
获取状态的两个方法
还是在org.apache.catlina.util.LifecycleBase:
在生命周期的相应方法中获取state属性,直接返回的state
public LifecycleState getState() {
return this.state;
}
public String getStateName() {
return this.getState().toString();
}
浅读tomcat架构设计之tomcat生命周期(2)的更多相关文章
- 浅读tomcat架构设计之tomcat容器Container(3)
浅读tomcat架构设计和tomcat启动过程(1) https://www.cnblogs.com/piaomiaohongchen/p/14977272.html 浅读tomcat架构设计之tom ...
- 浅读tomcat架构设计和tomcat启动过程(1)
一图甚千言,这张图真的是耽搁我太多时间了: 下面的tomcat架构设计代码分析,和这张图息息相关. 使用maven搭建本次的环境,贴出pom.xml完整内容: <?xml version=&qu ...
- Tomcat详解系列(2) - 理解Tomcat架构设计
Tomcat - 理解Tomcat架构设计 前文我们已经介绍了一个简单的Servlet容器是如何设计出来,我们就可以开始正式学习Tomcat了,在学习开始,我们有必要站在高点去看看Tomcat的架构设 ...
- 浅读tomcat架构设计之Pipeline-Valve管道(4)
tomcat Container容器处理请求是使用Pipeline-Valve管道来处理的,后续写的tomcat内存马,和他紧密结合 Pipeline-Valve是责任链模式,责任链模式是指在一个请求 ...
- Tomcat架构解析(一)-----Tomcat总体架构
Tomcat是非常常用的应用服务器,了解Tomcat的总体架构以及实现细节,对于理解整个java web也是有非常大的帮助. 一.Server 1.最简单的服务器结构 最简单的服务器结构如图所示: ...
- Tomcat架构解析(五)-----Tomcat的类加载机制
类加载器就是根据类的全限定名(例如com.ty.xxx.xxx)来获取此类的二进制字节流的代码模块,从而程序可以自己去获取到相关的类. 一.java中的类加载器 1.类加载器类别 java中的类加 ...
- 浅谈Android的Activity运行流程(生命周期)
关于Android的Activity运行流程,我们可以写一些程序来直观的查看Activity的运行流程.在这里我们使用Log工具来获取Activity运行日志.假如我们新建一个Android项目,Pr ...
- 【tomcat】servlet原理及其生命周期
1.什么是servlet? Servlet(Servlet Applet),全称Java Servlet,是用Java编写的服务器端程序.而这些Servlet都要实现Servlet这个接口.其主要功能 ...
- tomcat源码阅读之生命周期(LifeCycle)
一.事件机制流程: 1. 当外部事件源发生事件(比如点击了按钮,数据发生改变更新等)时,事件源将事件封装成事件对象Event: 2. 将事件对象交由对应的事件派发器Dispatcher ...
随机推荐
- Docker Swarm(四)Volume 数据(挂载)持久化
前言 为了获得最佳的性能和可移植性,应该避免将重要数据直接写入容器的可写层,而应使用数据卷或绑定挂载. 可以为集群中的服务创建两种类型的挂载,数据卷挂载(volume mounts)或绑定挂载(bin ...
- 利用stat指令查看文件创建时间
-shroot@test-W330-C30:/# stat * 文件:'b' 大小:4096 块:8 IO 块:4096 目录设备:802h/2050d Inode:5636097 硬链接:2权限:( ...
- STM32——EEPROM使用——(转载)
一.I2C接口读写EEPROM(AT24C02) --主模式,分别用作主发送器和主接收器.通过查询事件的方式来确保正常通信. 1.I 2C接口初始化 与其他对GPIO 复用的外设一样,它先调用了用户函 ...
- python 如何让俩个对象相等及如何让俩个对象具有相同的id值
- 高德Serverless平台建设及实践
导读 高德启动Serverless建设已经有段时间了,目前高德Serverless业务的峰值早已超过十万QPS量级,平台从0到1,QPS从零到超过十万,成为阿里集团内Serverless应用落地规模最 ...
- [Django高级之forms组件]
[Django高级之forms组件] forms组件之校验字段 # 第一步:定义一个类,继承forms.Form # 第二步:在类中写字段,要校验的字段,字段属性就是校验规则 # 第三步:实例化得到一 ...
- 巧用 iLocker 清理恶意程序
iLocker 作为 iGuard 网页防篡改系统的文件驱动过滤模块所衍生出来的独立应用,是一个文件防护工具,可以在文件系统驱动层检查文件操作,根据规则对文件操作进行放行或拦截,可以灵活细致地对文件访 ...
- 『动善时』JMeter基础 — 33、JMeter察看结果树的显示模式详解
目录 1.CSS Selector Tester视图 2.HTML查看器 (1)HTML视图 (2)HTML(download resources)视图 (3)HTML Source Formatte ...
- RCNN系列、Fast-RCNN、Faster-RCNN、R-FCN检测模型对比
RCNN系列.Fast-RCNN.Faster-RCNN.R-FCN检测模型对比 一.RCNN 问题一:速度 经典的目标检测算法使用滑动窗法依次判断所有可能的区域.本文则预先提取一系列较可能是物体的候 ...
- Python分析离散心率信号(上)
Python分析离散心率信号(上) 一些理论和背景 心率包含许多有关信息.如果拥有心率传感器和一些数据,那么当然可以购买分析包或尝试一些可用的开源产品,但是并非所有产品都可以满足需求.也是这种情况.那 ...