美文网首页
Tomcat学习笔记之启动分析(生命周期)(三)

Tomcat学习笔记之启动分析(生命周期)(三)

作者: 夏目手札 | 来源:发表于2019-05-07 21:49 被阅读0次

前言

在Catalina启动完成后,接下来就应该是Server的启动分析,但是由于后面的组件都与Lifecycle密不可分,所以这里先介绍Lifecycle机制。

生命周期

从上一篇文章中提到的#createStartDigester()方法中我们知道,Server的默认实现类是StandardServer,以StandardServer为入口,来看下Tomcat组件的生命周期类接口设计。


Tomcat生命周期类接口设计

简单介绍(该图的接口跟9.0版本有少许区别):

  • Lifecycle:定义了容器生命周期、容器状态转换及容器状态迁移事件的监听器注册和移除等主要接口;
  • LifecycleBase:作为Lifecycle接口的抽象实现类,运用抽象模板模式将所有容器的生命周期及状态转换衔接起来,此外还提供了生成LifecycleEvent事件的接口;
  • LifecycleSupport:提供有关LifecycleEvent事件的监听器注册、移除,并且使用经典的监听器模式,实现事件生成后触达监听器的实现;Tomcat9.0中已经被移除了;
  • MBeanRegistration:Java JMX框架提供的注册MBean的接口,引入此接口是为了便于使用JMX提供的管理功能;
  • LifecycleMBeanBase:Tomcat提供的对MBeanRegistration的抽象实现类,运用抽象模板模式将所有容器统一注册到JMX;

Lifecycle

直接来看Lifecycle接口中所包含的方法:

public interface Lifecycle {
    //省略生命周期状态。。。
    /**
     * 添加一个生命周期监听器到组件
     */
    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 void destroy() throws LifecycleException;
    /**
     * 获取当前组件的状态 返回LifecycleState对象
     */
    public LifecycleState getState();
    /**
     * 获取当前组件的状态 返回String
     */
    public String getStateName();
}

这里省略了生命周期状态的定义,源码注释上有着很好的解释几种状态的转换关系:

 *            start()
 *  -----------------------------
 *  |                           |
 *  | init()                    |
 * NEW -»-- INITIALIZING        |
 * | |           |              |     ------------------«-----------------------
 * | |           |auto          |     |                                        |
 * | |          \|/    start() \|/   \|/     auto          auto         stop() |
 * | |      INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»---  |
 * | |         |                                                            |  |
 * | |destroy()|                                                            |  |
 * | --»-----«--    ------------------------«--------------------------------  ^
 * |     |          |                                                          |
 * |     |         \|/          auto                 auto              start() |
 * |     |     STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
 * |    \|/                               ^                     |  ^
 * |     |               stop()           |                     |  |
 * |     |       --------------------------                     |  |
 * |     |       |                                              |  |
 * |     |       |    destroy()                       destroy() |  |
 * |     |    FAILED ----»------ DESTROYING ---«-----------------  |
 * |     |                        ^     |                          |
 * |     |     destroy()          |     |auto                      |
 * |     --------»-----------------    \|/                         |
 * |                                 DESTROYED                     |
 * |                                                               |
 * |                            stop()                             |
 * ----»-----------------------------»------------------------------

Lifecycle中用到了LifecycleListener,下面来看下:

public interface LifecycleListener {
    public void lifecycleEvent(LifecycleEvent event);
}

这里之定义了一个#lifecycleEvent()方法,接下来我们来看下LifecycleEvent类:

public final class LifecycleEvent extends EventObject {
   public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
       super(lifecycle);
       this.type = type;
       this.data = data;
   }
   /**
    * 与此事件关联的事件数据
    */
   private final Object data;
   /**
    * 此实例表示的事件类型
    */
   private final String type;

   public Object getData() {
       return data;
   }
   /**
     * 获取事件最初发生的对象,父类中定义的
     */
   public Lifecycle getLifecycle() {
       return (Lifecycle) getSource();
   }
   public String getType() {
       return this.type;
   }
}

LifecycleEvent类中主要定义了事件类型、事件关联的事件数据以及事件最初发生的对象。

LifecycleBase

  /**
     * 用于事件通知的已注册LifecycleListener列表
     */
    private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
    /**
     * 当前组件的状态,默认NEW,即对应LifecycleEvent为null
     */
    private volatile LifecycleState state = LifecycleState.NEW;
    private boolean throwOnFailure = true;
    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);
    }
    @Override
    public LifecycleListener[] findLifecycleListeners() {
        return lifecycleListeners.toArray(new LifecycleListener[0]);
    }
    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycleListeners.remove(listener);
    }
    /**
     * 允许子类通知所有已注册的LifecycleListener
     *
     */
    protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            listener.lifecycleEvent(event);
        }
    }
    @Override
    public final synchronized void init() throws LifecycleException {
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }

        try {
            //1. 设置状态为before_init,并通知所有已注册的LifecycleListener
            setStateInternal(LifecycleState.INITIALIZING, null, false);
            //2. 模板方法,子类实现
            initInternal();
            //3. 设置状态为after_init,并通知所有已注册的LifecycleListener
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.initFail", toString());
        }
    }

    @Override
    public final synchronized void start() throws LifecycleException {
        //1. 判断状态是否适合启动
        if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                LifecycleState.STARTED.equals(state)) {

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
            }

            return;
        }
        //2. 如果状态是NEW,重新init();如果状态是FAILED,直接stop()
        if (state.equals(LifecycleState.NEW)) {
            init();
        } else if (state.equals(LifecycleState.FAILED)) {
            stop();
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
            //3. 设置状态为before_start,并通知所有已注册的LifecycleListener
            setStateInternal(LifecycleState.STARTING_PREP, null, false);
            //4. 模板方法,子类实现
            startInternal();
            //5. 再判断一次装态,如果正常启动成功,设置状态为after_start,并通知所有已注册的LifecycleListener
            if (state.equals(LifecycleState.FAILED)) {
                // This is a 'controlled' failure. The component put itself into the
                // FAILED state so call stop() to complete the clean-up.
                stop();
            } else if (!state.equals(LifecycleState.STARTING)) {
                // Shouldn't be necessary but acts as a check that sub-classes are
                // doing what they are supposed to.
                invalidTransition(Lifecycle.AFTER_START_EVENT);
            } else {
                setStateInternal(LifecycleState.STARTED, null, false);
            }
        } catch (Throwable t) {
            // This is an 'uncontrolled' failure so put the component into the
            // FAILED state and throw an exception.
            handleSubClassException(t, "lifecycleBase.startFail", toString());
        }
    }

这里主要实现了#init()和#start()方法,并通过模板方法#xxxInternal()留给子类实现。

总结

通过上面的介绍,我们了解到Tomcat生命周期过程,Tomcat将内部所有组件都抽象为容器,使用Lifecycle接口和LifecycleBase抽像实现类为容器提供统一的生命周期管理,各个子容器只需要关心各自的具体实现,便于以后扩展更多的容器。

参考地址

Tomcat7.0源码分析——生命周期管理

相关文章

网友评论

      本文标题:Tomcat学习笔记之启动分析(生命周期)(三)

      本文链接:https://www.haomeiwen.com/subject/vqnigqtx.html