我们知道Tomcat的架构设计是清晰的、模块化的,其拥有很多组件,假如我们要启动Tomcat,可以一个一个启动组件,但这样启动有很多缺点,不仅麻烦,而且容易漏了组件启动,还会对后面动态组件扩展带来麻烦。难不成真要我们一个一个启动吗?其实未必,Tomcat的设计者提供了一个解决方案:用Lifecycle管理启动、停止、关闭。

从第一节的架构图可以看到各个核心组件有包含与被包含的关系,例如Server<-Service<-Container和Connector,最大的是Server,往下一层层包含。其实Tomcat就是以容器的方式来组织整个系统架构的,反映到数据结构就是树,树的根节点没有父节点,其它节点有且仅有一个父节点,每个父节点有零个或多个子节点,根容器与其他容器也有这样的特点。鉴于如此,可以通过父容器负责启动它的子容器,这样只要启动根容器,即可把其他所有容器都启动,达到统一启动、停止、关闭的效果。

Lifecycle作为统一的接口,把所有的启动、停止、关闭、生命周期相关方法都组织到一起,就可以很方便地管理Tomcat各个容器组件的生命周期。下面是Lifecycle接口详细的定义:

public interface Lifecycle {

public static final String BEFORE_INIT_EVENT = "before_init";

public static final String AFTER_INIT_EVENT = "after_init";

public static final String START_EVENT = "start";

public static final String BEFORE_START_EVENT ="before_start";

public static final String AFTER_START_EVENT = "after_start";

public static final String STOP_EVENT = "stop";

public static final String BEFORE_STOP_EVENT = "before_stop";

public static final String AFTER_STOP_EVENT = "after_stop";

public static final String AFTER_DESTROY_EVENT ="after_destroy";

public static final String BEFORE_DESTROY_EVENT ="before_destroy";

public static final String PERIODIC_EVENT = "periodic";

public static final String CONFIGURE_START_EVENT ="configure_start";

public static final String CONFIGURE_STOP_EVENT ="configure_stop";

public void addLifecycleListener(LifecycleListener listener);

public LifecycleListener[] findLifecycleListeners();

public void removeLifecycleListener(LifecycleListener listener);

public void init() throws LifecycleException;

public void start() throws LifecycleException;

public void stop() throws LifecycleException;

public LifecycleState getState();

public String getStateName();

}

从上面可以看出Lifecycle其实就是定义了一些状态常量跟几个方法,这里主要看下init、start、stop三个方法,所有需要被生命周期管理的容器都要实现这个接口,并且各自被父容器的相应方法调用,例如在初始化阶段,根容器Server会调用init方法,而在init方法里会调用它的子容器Service的init方法,以此类推。

在实际使用中,一般只有统一实现Lifecycle接口后才能实现统一调用,例如调用容器的init方法是这样子:((Lifecycle)容器).init()。下面简单看看Tomcat源码的Server是怎样调用init的。

public
final
synchronized
void init()
throws LifecycleException {

……

for (int
i = 0; i < services.length;
i++) {

services[i].init();

}

……

}

Server容器里面有若干多个Service实例,那么只要用一个for循环即可分别让每个Service调用init方法。这里的services[i]并没有用(Lifecycle)
显式转换类型,其实是因为Service也是一个接口,而这个接口已经继承了Lifecycle接口。

同样的,启动跟停止步骤也是通过类似的调用实现统一启动统一关闭。至此,我们对Tomcat的生命周期统一初始化、启动、关闭机制有了比较清晰的认识。

tomcat生命周期的管理——生命周期统一接口Lifecycle的更多相关文章

  1. 继承Application管理生命周期

    继承Application实现Android数据共享 http://www.jianshu.com/p/75a5c24174b2 jessyan提出一个思路,用Application + 接口来管理扩 ...

  2. React源码剖析系列 - 生命周期的管理艺术

    目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...

  3. ASP.NET Core Web API下事件驱动型架构的实现(二):事件处理器中对象生命周期的管理

    在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发.订阅和处理的流程.这种实现太简单了,百十行代码就展示了一个基本工作原理.然而,要将这样的解决方案运用到实际生产环境,还有很 ...

  4. React 源码剖析系列 - 生命周期的管理艺术

    目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...

  5. Mybatis核心类生命周期和管理

    Mybatis核心类生命周期和管理 原文链接:https://blog.csdn.net/qq1134550437/article/details/51960480 1.SqlSessionFacto ...

  6. 深入探索Glide图片加载框架:做了哪些优化?如何管理生命周期?怎么做大图加载?

    前言 Glide可以说是最常用的图片加载框架了,Glide链式调用使用方便,性能上也可以满足大多数场景的使用,Glide源码与原理也是面试中的常客. 但是Glide的源码内容比较多,想要学习它的源码往 ...

  7. 【PMP】项目生命周期和开发生命周期

    一.定义 项目生命周期:指项目从启动到完成所经历的一系列阶段. 开发生命周期:项目生命周期内通常有一个或多个阶段与产品.服务或成果的开发相关,这些阶段称为开发生命周期. 二.生命周期 预测型生命周期( ...

  8. Android Activity生命周期以及Fragment生命周期的区别与分析

    Android Fragment生命周期图: Activity生命周期图: 对照图: Fragment生命周期分析: 1. 当一个fragment被创建的时候,它会经历以下状态. onAttach() ...

  9. 微信APP生命周期、页面生命周期

    目录 小程序的启动流程 app生命周期 页面的生命周期 页面的生命周期(图) 小程序的启动流程 我们画一个图来表示一下,整个小程序的启动流程,我们就知道了: app生命周期 执行App()函数也就是注 ...

随机推荐

  1. 前端性能监控系统 & 前端数据分析系统

    前端监控系统 目前已经上线,欢迎使用! 背景:应工作要求,需要整理出前端项目的报错信息,尝试过很多统计工具,如: 腾讯bugly.听云.OneApm.还有一个忘记名字的工具. 因为各种原因,如: 统计 ...

  2. Struts2--二次提交

    在Struts2中,使用token的方式来防止二次提交.并且在默认的拦截器栈中提供了两个默认拦截器Token Interceptor和Token Session Interceptor.必须要在for ...

  3. 教你从手机中提取system镜像制作线刷救砖包的简单方法

    其实在制作刷机包的过程中,有时候没有官方或者第三方提供的救砖包(线刷),那怎么办?常规的方法有两种:(此处为常规方法,回读的方式暂不说明)     1.卡刷包转线刷包     2.dd命令导出分区镜像 ...

  4. AtCoder Beginner Contest 071 D - Coloring Dominoes

    Problem Statement We have a board with a 2×N grid. Snuke covered the board with N dominoes without o ...

  5. [Helvetic Coding Contest 2017 online mirror]

    来自FallDream的博客,未经允许,请勿转载,谢谢, 第一次在cf上打acm...和同校大佬组队打 总共15题,比较鬼畜,最后勉强过了10题. AB一样的题目,不同数据范围,一起讲吧 你有一个背包 ...

  6. xml 制作 RSS 订阅源

    首先制作一个 RSS 模板,模板的文件名是 feed.xml,代码如下: <?xml version="1.0" encoding="utf-8"?> ...

  7. java集合之HashMap源码解读

    源自:jdk1.8.0_121 HashMap继承自AbstractMap,实现了Map.Cloneable.Serializable. HashMap内部是由数组.链表.红黑树实现的 变量 // 默 ...

  8. Linux 下查看tomcat版本

    1.echo $JAVA_HOME 2.进入jdk路径 3.java -version

  9. IOS JavaScriptCore介绍

    本文主要转自:https://www.jianshu.com/p/cdaf9bc3d65d http://blog.csdn.net/u011993697/article/details/515772 ...

  10. TCP/UDP的区别

    TCP与UDP区别 TCP提供的是面向连接的.可靠的数据流传输: UDP提供的是非面向连接的.不可靠的数据流传输. TCP提供可靠的服务,通过TCP连接传送的数据,无差错.不丢失,不重复,按序到达:U ...