3. TOMCAT学习——TOMCAT的生命周期

TOMCAT包含很多组件。这些组件需要跟随TOMCAT一起启动和关闭。如何达到这种目的呢?TOMCAT引入了生命周期的概念。

生命周相关的接口和类包括

1. org.apache.catalina.Lifecycle 
2. org.apache.catalina.LifecycleListener
3. org.apache.catalina.LifecycleEvent
4. org.apache.catalina.util.LifecycleSupport

下面分别介绍一下这些类
  • org.apache.catalina.Lifecycle

    生命周期接口。所有想要被生命周期体系管理的对象都要继承于它。
    下面是Lifecycle接口的主要方法。

    //添加事件监听器
    public void addLifecycleListener(LifecycleListener listener);
    //查找所有的事件监听器
    public LifecycleListener[] findLifecycleListeners();
    //删除事件监听器
    public void removeLifecycleListener(LifecycleListener listener);
    //启动
    public void start() throws LifecycleException;
    //停止
    public void stop() throws LifecycleException;
  • org.apache.catalina.LifecycleListener

    生命周期监听接口。每个继承Lifecycle的对象可以添加多个监听器。
    下面是LifecycleListener的主要方法。

    //这个方法的内容是监听器被通知时需要做的事
    public void lifecycleEvent(LifecycleEvent event);
  • org.apache.catalina.LifecycleEvent

    生命周期体系的事件类。TOMCAT的生命周期事件包括以下9种:

    • INIT_EVENT
    • START_EVENT
    • BEFORE_START_EVENT
    • AFTER_START_EVENT
    • STOP_EVENT
    • BEFORE_STOP_EVENT
    • AFTER_STOP_EVENT
    • DESTROY_EVENT
    • PERIODIC_EVENT

    这些事件类型定义在Lifecycle接口中。可以把LifecycleEvent理解成生命周期体系中的Bean对象,一个用于传递数据的数据结构。其属性如下

    //一个附加对象,没有实际用途,
    //可以理解为备注(TOMCAT中有些代码用这个对象来记录日志)
    //也可以直接忽略
    private Object data = null;

    //Lifecycle对象,触发事件的对象
    private Lifecycle lifecycle = null;
    
    //事件类型
    private String type = null;
  • org.apache.catalina.util.LifecycleSupport

    可以理解为助手类,实现了Lifecycle中除了startstop之外的三个接口。其构造方法需要传入一个Lifecycle对象。在TOMCAT中很多Lifecycle的实例会使用LifecycleSupport类来为自己管理事件监听器。看一下LifecycleSupport的主要代码。

    //构造函数,持有一个Lifecycle的引用
    public LifecycleSupport(Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
    }

    //Lifecycle的引用
    private Lifecycle lifecycle = null;

    //用于维护当前Liftcycle的监听器列表
    private LifecycleListener listeners[] = new LifecycleListener[0];
    
    //添加/移除监听器的时候需要加锁,这是加锁使用的锁对象
    private final Object listenersLock = new Object(); // Lock object for changes to listeners

    //添加监听器,向listeners中加入一个监听器对象
    public void addLifecycleListener(LifecycleListener listener) {
      synchronized (listenersLock) {
          LifecycleListener results[] =
            new LifecycleListener[listeners.length + 1];
          for (int i = 0; i < listeners.length; i++)
              results[i] = listeners[i];
          results[listeners.length] = listener;
          listeners = results;
      }
    }


    //返回监听当前对象的所有监听器
    public LifecycleListener[] findLifecycleListeners() {
        return listeners;
    }


    //触发监听器,传入要触发的监听器的类型
    public void fireLifecycleEvent(String type, Object data) {
        if (Lifecycle.INIT_EVENT.equals(type)) {
            state = "INITIALIZED";
        } else if (Lifecycle.BEFORE_START_EVENT.equals(type)) {
            state = "STARTING_PREP";
        } else if (Lifecycle.START_EVENT.equals(type)) {
            state = "STARTING";
        } else if (Lifecycle.AFTER_START_EVENT.equals(type)) {
            state = "STARTED";
        } else if (Lifecycle.BEFORE_STOP_EVENT.equals(type)) {
            state = "STOPPING_PREP";
        } else if (Lifecycle.STOP_EVENT.equals(type)) {
            state = "STOPPING";
        } else if (Lifecycle.AFTER_STOP_EVENT.equals(type)) {
            state = "STOPPED";
        } else if (Lifecycle.DESTROY_EVENT.equals(type)) {
            state = "DESTROYED";
        }
        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = listeners;
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);
    }

    //移除监听器,在listeners中移除一个监听器对象
    public void removeLifecycleListener(LifecycleListener listener) {
        synchronized (listenersLock) {
            int n = -1;
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i] == listener) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                return;
            LifecycleListener results[] =
              new LifecycleListener[listeners.length - 1];
            int j = 0;
            for (int i = 0; i < listeners.length; i++) {
                if (i != n)
                    results[j++] = listeners[i];
            }
            listeners = results;
        }
    }


生命周期体系的使用

上面我们简单描述了一下生命周期体系中相关的一些类。接下来我们看一下这个体系的简单使用方法。

在这里插入图片描述

  1. MyLifecycle中初始化一个LifecycleSupport类。
  2. 在程序中使用LifecycleSupportaddLifecycleListener 方法,为 MyLifecycle注册监听器。
  3. MyLifecycle的状态发生变化的时候,开发者就可以调用LifecycleSupportfireLifecycleEvent 方法触发事件,告知所有注册的监听器:“XXX事件发生了”。
  4. fireLifecycleEvent 方法会调用监听器(LifecycleListener)的 lifecycleEvent 方法来处理对应的事件。由于LifecycleListener只是个接口,所以具体的处理逻辑在监听器的实现类中实现。

再说说之前忽略的 startstop 方法

TOMCAT容器的启动和关闭全都依赖于各容器的 startstop 方法。众所周知TOMCAT的容器是有层级关系的,如: 父容器 Context 和子容器 WrapperContext容器启动的时候必须要去启动与他相关联的子容器Wrapper。而Context的启动又是由他的父容器来触发,以此类推。因此,TOMCAT启动时只需要调用最上层容器的 start 方法,同样的,关闭时也只需要调用最上层容器的 stop 方法。
如下图
在这里插入图片描述

当然TOMCAT完整的启动链肯定没有这么简单,但是我们在这里忽略其他细节,只关注 startstop 方法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值