浅读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)的更多相关文章

  1. 浅读tomcat架构设计之tomcat容器Container(3)

    浅读tomcat架构设计和tomcat启动过程(1) https://www.cnblogs.com/piaomiaohongchen/p/14977272.html 浅读tomcat架构设计之tom ...

  2. 浅读tomcat架构设计和tomcat启动过程(1)

    一图甚千言,这张图真的是耽搁我太多时间了: 下面的tomcat架构设计代码分析,和这张图息息相关. 使用maven搭建本次的环境,贴出pom.xml完整内容: <?xml version=&qu ...

  3. Tomcat详解系列(2) - 理解Tomcat架构设计

    Tomcat - 理解Tomcat架构设计 前文我们已经介绍了一个简单的Servlet容器是如何设计出来,我们就可以开始正式学习Tomcat了,在学习开始,我们有必要站在高点去看看Tomcat的架构设 ...

  4. 浅读tomcat架构设计之Pipeline-Valve管道(4)

    tomcat Container容器处理请求是使用Pipeline-Valve管道来处理的,后续写的tomcat内存马,和他紧密结合 Pipeline-Valve是责任链模式,责任链模式是指在一个请求 ...

  5. Tomcat架构解析(一)-----Tomcat总体架构

    Tomcat是非常常用的应用服务器,了解Tomcat的总体架构以及实现细节,对于理解整个java web也是有非常大的帮助. 一.Server   1.最简单的服务器结构 最简单的服务器结构如图所示: ...

  6. Tomcat架构解析(五)-----Tomcat的类加载机制

    类加载器就是根据类的全限定名(例如com.ty.xxx.xxx)来获取此类的二进制字节流的代码模块,从而程序可以自己去获取到相关的类. 一.java中的类加载器   1.类加载器类别 java中的类加 ...

  7. 浅谈Android的Activity运行流程(生命周期)

    关于Android的Activity运行流程,我们可以写一些程序来直观的查看Activity的运行流程.在这里我们使用Log工具来获取Activity运行日志.假如我们新建一个Android项目,Pr ...

  8. 【tomcat】servlet原理及其生命周期

    1.什么是servlet? Servlet(Servlet Applet),全称Java Servlet,是用Java编写的服务器端程序.而这些Servlet都要实现Servlet这个接口.其主要功能 ...

  9. tomcat源码阅读之生命周期(LifeCycle)

    一.事件机制流程: 1.     当外部事件源发生事件(比如点击了按钮,数据发生改变更新等)时,事件源将事件封装成事件对象Event: 2.     将事件对象交由对应的事件派发器Dispatcher ...

随机推荐

  1. Tracert 命令

    Tracert 命令 Tracert 命令的作用 Tracert命令诊断实用程序通过向目标计算机发送具有不同生存时间的ICMP数据包,来确定至目标计算机的路由,也就是说用来跟踪一个消息从一台计算机到另 ...

  2. linux .tar.xz 文件解压和压缩

    场景:centos7.0下文件格式为xxx.tar.xz,解压和压缩命令: 压缩 tar -Jcf linux-3.10.0-123.13.1.el7.tar.xz(文件名) linux-3.10.0 ...

  3. IDEA 常用快捷键列表【建议收藏】

    编辑代码 快捷键 说明 Alt+Enter 导入包.自动变量命名等(万能快捷键) Ctrl+X 删除行 Ctrl+Y 删除当前行 Ctrl+D 复制行 Alt+Shift+Up/Down或Ctrl+S ...

  4. Go语言的函数06---闭包函数

    package main import "fmt" /* 李逵和武松的Study方法的逻辑是几乎一模一样的 然而为了分别保存两人的学习进度,需要开辟两个全局变量,函数内部的需要使用 ...

  5. ReentrantLock修饰类文件,实现按类获取锁的逻辑

    1.ReentrantLock 给类文件加锁,实现类似synchronized(class)的功能 核心是类文件中,使用static修饰的reentrantLock对象 public class So ...

  6. GPU上的基本线性代数

    GPU上的基本线性代数 cuBLAS库提供了基本线性代数子例程(BLAS)的GPU加速实现.cuBLAS通过针对NVIDIA GPU进行了高度优化的嵌入式行业标准BLAS API来加速AI和HPC应用 ...

  7. GPU编程和流式多处理器(七)

    6. 杂项说明 6.1. warp级原语 warp作为执行的原始单元(自然位于线程和块之间),重要性对CUDA程序员显而易见.从SM 1.x开始,NVIDIA开始添加专门针对thread的指令. Vo ...

  8. 使用Tensorize评估硬件内部特性

    使用Tensorize评估硬件内部特性 这是有关如何在TVM中执行张量的入门文档. 通过使用调度原语tensorize,人们可以用相应的内部函数代替计算单元,从而轻松利用handcrafted mic ...

  9. 适用于Linux 2的Windows子系统上的CUDA

    适用于Linux 2的Windows子系统上的CUDA Announcing CUDA on Windows Subsystem for Linux 2 为了响应大众的需求,微软在2020年5月的构建 ...

  10. Java日期时间API系列39-----中文语句中的时间语义识别(time NLP 输入一句话,能识别出话里的时间)原理分析

    NLP (Natural Language Processing) 是人工智能(AI)的一个子领域.自然语言是人类智慧的结晶,自然语言处理是人工智能中最为困难的问题之一(来自百度百科). 其中中文更是 ...