我们知道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的生命周期统一初始化、启动、关闭机制有了比较清晰的认识。

最新文章

  1. hdu1247 Hat’s Words
  2. bzoj 1977
  3. win32控制台消息机制
  4. Java设计模式-Builder生成器模式
  5. 在EF的code frist下写稳健的权限管理系统:仓储设计(三)
  6. underscorejs-indexBy学习
  7. 【转】解决java.lang.IllegalStateException: The content of the adapter has changed but ListView...的问题
  8. windows下配置Java环境变量
  9. javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。
  10. 用PHP ping 一个 IP
  11. springMVC web项目 对访问数据库的用户名密码进行加密解密
  12. Vue的组件
  13. 【English】20190428
  14. c/c++ 重载运算符 关系,下标,递增减,成员访问的重载
  15. native-echarts 图形组件
  16. noexcept(c++11)
  17. Restful风格wcf调用4——权限认证
  18. 关于vue跨域名对接微信授权认证和APP授权认证
  19. Git之修复Bug流程
  20. Ext4文件系统架构分析(三)

热门文章

  1. StandardContext
  2. 线段树——codevs 1690 开关灯
  3. [HNOI 2017]抛硬币
  4. [HNOI2016]序列
  5. [BZOJ]4810: [Ynoi2017]由乃的玉米田
  6. [UOJ UR #4追击圣诞老人]
  7. 2017ACM/ICPC广西邀请赛-重现赛 1004.Covering
  8. C语言程序设计预报作业
  9. Java 第一次作业
  10. 07_Linux目录文件操作命令4解压缩,文件查找_我的Linux之路