zoukankan      html  css  js  c++  java
  • Tomcat知多少 -- 组件生命周期Lifecycle

    Tomcat中存在着诸多的组件,如Server、Service、Engine、Host、Context等,这些组件都遵从Tomcat的生命周期管理,比如当Catalina调用start()方法启动Tomcat时,这些组件会随之启动,当调用stop()关闭时,这些组件会随之关闭。

    理解Tomcat的生命周期管理对于分析Tomcat源码很有帮助,方便快速理清源码结构,深入源码时也会有迹可循。

    生命周期的顶层设计

    Tomcat生命周期管理的顶层设计如下图所示:

    接口Lifecycle定义了生命周期中的四种动作以及生命周期中的各种事件名称(这里没有列出);

    枚举类LifecycleState定义了生命周期中的各种状态;

    LifecycleBaseLifecycle接口的抽象实现类,像StandardServerStandardSevice等Tomcat的核心组件都是它的子类,该类主要内容是规定了四种动作发生时组件状态之间的转换,以及自动调用先前注册的事件监听动作。它拥有一个LifecycleState类型的成员变量,用于记录组件的当前状态,还使用一个容器变量来存储注册在该组件上的事件监听器;

    LifecycleEvent用于表示声明周期中发生的一个事件,它的成员有表示事件来源的组件source,发生的事件类型type,以及事件发生时携带的数据;

    LifecycleListener是事件监听器的接口,它只有一个方法声明lifecycleEvent(event:LifecycleEvent),该方法接收一个LifecycleEvent实例对象,其具体实现类将根据事件类型来执行相应的动作(可以查看VersionLoggerListener的源码作为一个实现的参考)。

    状态转移图

    LifecycleBase规定的四种动作发生时组件状态之间的转换图如下所示。

    可以看到,生命周期中的状态转移还是比较复杂的,各组件由NEW状态开始,到DESTROYED状态结束,中间通过不同的方法调用实现合法的状态转移,而不合法的状态转移都会导致状态置为FAILED,接着调用destroy()方法来销毁。

    这一块在实现上实际上是模板方法模式一个应用,通过实现Lifecycle接口中的四个方法来定义状态转移,同时又声明四个抽象方法xxxInternal(),将具体的功能留给子类来实现。

    当然在状态转以上,Tomcat并没有使用到状态模式,而是使用了许多if ... else...判断语句来定义合法的状态转移,这样的好处在于避免了为每个状态定义一个类,减少了类的数目。

    事件监听

    LifecycleBase使用观察者模式来实现了事件的响应处理。

    首先,它定义了一个List容器用于保存注册的监听器:

    /**
     * The list of registered LifecycleListeners for event notifications.
     */
    private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
    

    这里使用了CopyOnWriteArrayList,通过读写分离来提高并发环境下的事件响应效率。

    最后,通过protected void fireLifecycleEvent(String type, Object data)方法响应相应事件。

    如下图所示,以init()的调用为例:

    首先使用setStateInternal()方法改变状态为INITLALIZING,该方法内部会调用fireLifecycleEvent()方法,接着会根据事件类型先创建一个LifecycleEvent实例event,然后将event作为参数调用LifecycleListenerlifecycleEvent()方法,该方法就是各个具体的监听器响应事件的地方。随后具体的初始化动作在initInternal()中完成后,在设置状态为INITIALIZED,同时也会触发相关的监听事件。

    -------------------------------------
    吾生也有涯,而知也无涯。
  • 相关阅读:
    PL/SQL集合(一):记录类型(TYPE 类型名称 IS RECORD)
    PL/SQL编程基础(五):异常处理(EXCEPTION)
    PL/SQL编程基础(四):程序控制(IF,CASE,FOR,LOOP,WHILE LOOP,EXIT,CONTINUE)
    PL/SQL编程基础(三):数据类型划分
    PL/SQL编程基础(二):变量的声明、赋值、(赋值、连接、关系、逻辑)运算符
    PL/SQL编程基础(一):PL/SQL语法简介(匿名PL/SQL块)
    SQL Fundamentals || DCL(Data Control Language) || 角色ROLES
    SQL Fundamentals || DCL(Data Control Language) || 系统权限&对象权限管理(GRANT&REVOKE)
    SQL Fundamentals || DCL(Data Control Language) || 用户管理&Profile概要文件
    Oracle Schema Objects——PARTITION
  • 原文地址:https://www.cnblogs.com/SanjiApollo/p/12853190.html
Copyright © 2011-2022 走看看