Tomcat的生命周期管理简要分析

2016-12-29 14:24
爆笑每天 2016-12-28 09:43

在上一篇文章中:Tomcat服务器顶层结构和启动过程 对Tomcat的整体架构有了一个大致的了解,这一篇主要是学习一下Tomcat的整个生命周期的管理。

Tomcat的生命周期管理使用了观察者模式,使Tomcat的生命周期管理机制设计的非常优雅,在Tomcat启动时,只需要启动一个Server组件,就会启动所有的容器及对应的组件,并且触发这些容器的监听者,完成启动过程的设置。可以说是“一键式”启动的。停止过程也是一样。

一、观察者模式简单描述

(1)观察者模式有时被称作:发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式的应用非常广泛,如Java AWT事件模型,Servlet的监听器,spring事件处理机制以及Tomcat生命周期管理机制等等。

(2)观察者模式解决的问题

将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。

(3)观察者模式中有3类角色对象:

1、抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

2、具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。

3、抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

4、具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

(4)观察者模式的类图:

Tomcat的生命周期管理简要分析

二、Tomcat的生命周期管理相关类

关于Tomcat的生命周期管理所涉及的相关类主要有:

(1)Lifecycle:相当于抽象主题角色,所有的容器类与组件实现类都实现了这个接口。如StandardContext

(2)LifecycleListener:相当于抽象观察者角色,具体的实现类有ContextConfig, HostConfig, EngineConfig类,它们在容器启动时与停止时触发。

(3)LifecycleEvent:生命周期事件,对主题与发生的事件进行封装。

(4)LifecycleSupport:生命周期管理的实用类,提供对观察者的添加,删除及通知观察者的方法。(Tomcat release 9.0.x版本中没有用到这个)

(5)LifecycleException:生命周期异常类。

三、Lifecycle接口介绍

组件生命周期方法的通用接口。org.apache.catalina.Lifecycle Tomcat通过Lifecycle接口统一管理生命周期,所有有生命周期的组件都要实现Lifecycle接口,以便提供一致的机制去启动和停止组件。Lifecycle接口内容如下:

Tomcat的生命周期管理简要分析

上图中可以看出Lifecycle接口一共做了四件事情:

(1)定义了13个String类型常量:这些常量信息用于LifecycleEvent事件的type属性中,作用是区分组件发出的LifecycleEvent事件是的状态(如初始化前、启动前、启动中等)。这种设计方法可以让多种状态都发送同一种类型的时间,然后用其中的一个属性类区分状态而不用定义多种事件。

(2)定义了3个管理监听器的方法:addLifecycleListener、findLifecycleListeners和removeLifecycleListener。分别用来添加、查找和删除LifecycleListener类型的监听器。源码如下图所示:

Tomcat的生命周期管理简要分析

(3)定义了4个生命周期的方法:init、start、stop和destory,用于执行生命周期的各个阶段,接口定义如下:

Tomcat的生命周期管理简要分析

(4)定义了获取当前和状态的两个方法: getState和getStateName,用来获取当前的状态,getState的返回值LifecycleState是枚举类型,里边列举了生命周期的各个节点,getStateName方法返回String类型的状态的名字。

完整的Lifecycle 接口定义代码如下:

Tomcat的生命周期管理简要分析

四、Lifecycle接口默认实现LifecycleBase

Lifecycle接口的默认实现是org.apache.catalina.util.LifecycleBase ,在LifecycleBase实现类中实现了Lifecycle接口中定义的方法,类结构图如下:

Tomcat的生命周期管理简要分析

(1)3个管理监听器的方法

可以看出LifecycleBase定义了一个lifecycleListeners 集合用于保存所有的监听器,然后并定义了添加、删除、查找和执行监听器的方法;

(2)4个生命周期的方法:init、start、stop和destory

Tomcat的生命周期管理简要分析

这里对四个生命周期,只讨论init方法,其他三种大致相同。

在init方法中调用了所对应的模板方法initInternal() 该方法并没有具体的实现,而是让子类去具体的实现,因此对于子类来说,执行生命周期的方法就是:initInternal、startInternal、stopInternal、destroyInternal;

(3)定义了获取当前和状态的两个方法:getState和getStateName

Tomcat的生命周期管理简要分析

在生命周期相应的方法中已经设置了state的属性,所以通过这两个方法就可以简单的实现获取state。

五、再谈Tomcat中的观察者模式

Tomcat中的观察者模式:

Tomcat的生命周期管理简要分析

Tomcat中Lifecycle就是抽象的主题。

然后像StandardEngine、StandardHost、StandardContext、StandardServer这类Container对象,都是具体主题。

LifecycleListener定义了观察者想要执行的方法。就是前面提到的,如果观察者对主题的某个动作感兴趣,他就会做自己的动作,这个动作就是LifecycleListener里的方法。当然LifecycleListener是一个接口,用户可以定义各种具体的观察者。

Tomcat对观察者模式做了很好的扩展,他增加了一个LifecycleSupport来代替主题管理多个观察者,把功能模块分得更清晰,LifecycleSupport中定义了一个LifecycleListener的数组。主题中某动作发生时,LifecycleSupport会遍历此数组,对每一个listener调用它们像要做的方法。

下面的方法就是LifecycleSupport通知各个LifecycleListener某事件发生了。

Tomcat的生命周期管理简要分析

Tomcat中将事件定义为LifecycleEvent

Tomcat的生命周期管理简要分析

事件有一个属性type,用来标明事件的类型。

也就是说Tomcat中观察者模式流程:

1、将观察者listener增加到LifecycleSupport的listener数组中

2、当container(主题)做某些动作的时候,会生成一个LifecycleEvent对象,这个对象标明当前这个动作是一个什么事件,然后LifecycleSupport会通知listener数组中的每一个观察者该事件的发生。

3、listener会根据LifecycleEvent判断事件的类型,完成相应的动作。

注:Java学习和爱好者可以加QQ群:586855725,相关技术,技术交流,工作讨论,包括Java、Spring、MyBatis、Spring MVC、Dubbo、数据库、Linux、项目开发工具等,群文件含有大量学习资料,欢迎加入下载。

本文为头条号作者发布,不代表今日头条立场。