Tomcat生命周期治理

各种组件如何对立治理

Tomcat的架构设计是清晰的、模块化、它领有很多组件,退出在启动Tomcat时一个一个组件启动,很容易脱漏组件,同时还会对前面的动静组件拓展带来麻烦。如果采纳咱们传统的形式的话,组件在启动过程中如果产生异样,会很难治理,比方你的下一个组件调用了start办法,然而如果它的下级组件还没有start甚至还没有init的话,Tomcat的启动会十分难治理,因而,Tomcat的设计者提出一个解决方案:用Lifecycle治理启动,进行、敞开。

生命周期对立接口

Tomcat外部架构中各个外围组件有蕴含与被蕴含关系,例如:Server蕴含了Service.Service又蕴含了Container和Connector,这个构造有一点像数据结构中的树,树的根结点没有父节点,其余节点有且仅有一个父节点,每一个父节点有0至多个子节点。所以,咱们能够通过父容器启动它的子容器,这样只有启动根容器,就能够把其余所有的容器都启动,从而达到了对立的启动,进行、敞开的成果。

所有所有组件有一个对立的接口——Lifecycle,把所有的启动、进行、敞开、生命周期相干的办法都组织到一起,就能够很方便管理Tomcat各个容器组件的生命周期。

Lifecycle其实就是定义了一些状态常量和几个办法,次要办法是init,start,stop三个办法。

例如:Tomcat的Server组件的init负责遍历调用其蕴含所有的Service组件的init办法。

留神:Server只是一个接口,实现类为StandardServer,有意思的是,StandardServer没有init办法,init办法是在哪里,其实是在它的父类LifecycleBase中,这个类就是对立的生命周期治理。

COPYpublic class StandardService extends LifecycleMBeanBase implements Service    public abstract class LifecycleMBeanBase extends LifecycleBase        implements JmxEnabled

LifecycleBase

COPYpublic abstract class LifecycleBase implements Lifecycle {      @Override    public final synchronized void init() throws LifecycleException {        //这个就是为了避免 组件启动的程序不对        if (!state.equals(LifecycleState.NEW)) {            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);        }        try {            //只打印外围组件            if(this.getClass().getName().startsWith("org.apache.catalina.core")||this.getClass().getName().startsWith("org.apache.catalina.connector")){                System.out.println(this.getClass()+"--init()");            }            setStateInternal(LifecycleState.INITIALIZING, null, false);            //调用子类的initInternal办法            initInternal();            setStateInternal(LifecycleState.INITIALIZED, null, false);        } catch (Throwable t) {            handleSubClassException(t, "lifecycleBase.initFail", toString());        }    }   }

所以StandardServer最终只会调用到initInternal办法,这个办法会初始化子容器Service的init办法

为什么LifecycleBase这么玩,其实很多架构源码都是这么玩的,包含JDK的容器源码都是这么玩的,一个类,有一个接口,同时形象一个形象骨架类,把通用的实现放在形象骨架类中,这样设计就不便组件的治理,应用LifecycleBase骨架抽象类,在形象办法中就能够进行对立的解决。

LifeCycle源码剖析

作用

组件生命周期办法的通用接口。 Catalina组件能够实现此接口(以及它们反对的性能的适当接口),以便提供统一的机制来启动和进行组件

状态图

Tomcat中的事件触发是通过这些状态来断定的。
COPY*            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接口对立治理Tomcat生命周期。一共做了4件事:

  • 定义13个string类型常量,用于LifecycleEvent工夫的type属性中,用于辨别组件收回的LifecycleEvent事件时的状态。
  • 定义三个治理监听器的办法,addLifecycleListener、findLifecycleListeners、removeLifecycleListener。
  • 定义4个生命周期的办法,init、start、stop、destory,用于执行生命周期的各个阶段的操作。
  • 定义了获取以后状态的两个办法,getState、getStateName、用于获取以后的状态。
COPYpublic interface Lifecycle {    // 13个状态常量值    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";    // 3个监听器办法    public void addLifecycleListener(LifecycleListener listener);    public LifecycleListener[] findLifecycleListeners();    public void removeLifecycleListener(LifecycleListener listener);    // 4个生命周期办法    public void init() throws LifecycleException;    public void start() throws LifecycleException;    public void stop() throws LifecycleException;    public void destroy() throws LifecycleException;    // 2个以后状态办法    public LifecycleState getState();    public String getStateName();}

默认实现类

COPYpublic abstract class LifecycleBase implements Lifecycle {    // 源组件的以后状态,不同状态触发不同事件    private volatile LifecycleState state = LifecycleState.NEW;}

监听器相干办法

事件监听器须要三个参与者:

  • 事件对象:用于封装事件的信息,在事件监听器接口的同一办法中作为参数应用,继承自java.util.EventObject类。
  • 事件源:触发事件的源头,不同事件源触发不同事件类型。
  • 事件监听器:负责监听事件源收回的事件。实现 java.util.EventListener 接口。
COPY// 用于事件告诉的已注册LifecycleListener列表private final List<LifecycleListener> lifecycleListeners =     new CopyOnWriteArrayList<>();@Overridepublic void addLifecycleListener(LifecycleListener listener) {    lifecycleListeners.add(listener);}@Overridepublic LifecycleListener[] findLifecycleListeners() {    return lifecycleListeners.toArray(new LifecycleListener[0]);}@Overridepublic void removeLifecycleListener(LifecycleListener listener) {    lifecycleListeners.remove(listener);}// 子类依据以后状态触发不同事件,实现不同操作protected void fireLifecycleEvent(String type, Object data) {    LifecycleEvent event = new LifecycleEvent(this, type, data);    for (LifecycleListener listener : lifecycleListeners) {        listener.lifecycleEvent(event);    }}

生命周期办法

LifecycleBase 类是Lifecycle 接口的默认实现,所有实现了生命周期的组件都间接或者间接的继承自LifecycleBase。
init办法
COPY@Overridepublic final synchronized void init() throws LifecycleException {    // 只有 NEW 状态能够调用    if (!state.equals(LifecycleState.NEW)) {        invalidTransition(Lifecycle.BEFORE_INIT_EVENT);    }    // 设置 生命周期状态 -- INITIALIZING,触发相应事件    setStateInternal(LifecycleState.INITIALIZING, null, false);    // 模板办法,由具体子类实现    initInternal();    // 执行实现,设置生命周期状态 -- INITIALIZED,触发相应事件    setStateInternal(LifecycleState.INITIALIZED, null, false);}
Start办法
COPY@Overridepublic final synchronized void start() throws LifecycleException {    // 此三种状态不执行    if (LifecycleState.STARTING_PREP.equals(state) ||              LifecycleState.STARTING.equals(state) ||        LifecycleState.STARTED.equals(state)) {        return;    }    // NEW 状态 执行 init 办法    if (state.equals(LifecycleState.NEW)) {        init();    // 启动失败,调用 stop 办法    } else if (state.equals(LifecycleState.FAILED)) {        stop();    // 其它状态,非法操作    } else if (!state.equals(LifecycleState.INITIALIZED) &&            !state.equals(LifecycleState.STOPPED)) {        throw new LifecycleException()    }    // 设置启动状态为 STARTING_PREP【开始筹备】    setStateInternal(LifecycleState.STARTING_PREP, null, false);    startInternal();    // 调用实现后判断组件启动状态    if (state.equals(LifecycleState.FAILED)) {        stop();    } else if (!state.equals(LifecycleState.STARTING)) {        throw new LifecycleException();    } else {        setStateInternal(LifecycleState.STARTED, null, false);    }}
stop办法
COPY@Overridepublic final synchronized void stop() throws LifecycleException {    // STOPPING_PREP、STOPPING、STOPPED此三种状态不予执行    if (LifecycleState.STOPPING_PREP.equals(state) ||         LifecycleState.STOPPING.equals(state) ||        LifecycleState.STOPPED.equals(state)) {        return;    }    // 如果状态为 NEW、批改为 STOPPED    if (state.equals(LifecycleState.NEW)) {        state = LifecycleState.STOPPED;        return;    }    // 不为 STARTED、FAILED 2种状态,抛出异样    if (!state.equals(LifecycleState.STARTED) &&         !state.equals(LifecycleState.FAILED)) {        throw new LifecycleException();    }    try {        // 启动失败,触发事件,否则设置生命周期状态        if (state.equals(LifecycleState.FAILED)) {            fireLifecycleEvent(BEFORE_STOP_EVENT, null);        } else {            setStateInternal(LifecycleState.STOPPING_PREP, null, false);        }        // 调用模板办法        stopInternal();        if (!state.equals(LifecycleState.STOPPING) &&             !state.equals(LifecycleState.FAILED)) {            throw new LifecycleException();        }        setStateInternal(LifecycleState.STOPPED, null, false);    } catch (Throwable t) {        setStateInternal(LifecycleState.FAILED, null, false);        throw new LifecycleException();    } finally {        if (this instanceof Lifecycle.SingleUse) {            setStateInternal(LifecycleState.STOPPED, null, false);            destroy();        }    }}
destroy办法
COPY@Overridepublic final synchronized void destroy() throws LifecycleException {    // 启动失败,先调用 stop 办法    if (LifecycleState.FAILED.equals(state)) {        stop();    }    // DESTROYING、DESTROYED不执行了    if (LifecycleState.DESTROYING.equals(state) ||        LifecycleState.DESTROYED.equals(state)) {        return;    }    // 非法状态    if (!state.equals(LifecycleState.STOPPED) &&        !state.equals(LifecycleState.FAILED) &&        !state.equals(LifecycleState.NEW) &&        !state.equals(LifecycleState.INITIALIZED)) {        throw new LifecycleException();    }    try {        setStateInternal(LifecycleState.DESTROYING, null, false);        destroyInternal();        setStateInternal(LifecycleState.DESTROYED, null, false);    } catch (Throwable t) {        setStateInternal(LifecycleState.FAILED, null, false);        throw new LifecycleException();    }}
设置状态办法
COPYprivate synchronized void setStateInternal(LifecycleState state,        Object data, boolean check) throws LifecycleException {    // 查看参数    if (check) {        if (state == null) {            throw new LifecycleException();            return;        }        if (!(state == LifecycleState.FAILED ||                (this.state == LifecycleState.STARTING_PREP &&                        state == LifecycleState.STARTING) ||                (this.state == LifecycleState.STOPPING_PREP &&                        state == LifecycleState.STOPPING) ||                (this.state == LifecycleState.FAILED &&                        state == LifecycleState.STOPPING))) {            throw new LifecycleException();        }    }    this.state = state;    String lifecycleEvent = state.getLifecycleEvent();    if (lifecycleEvent != null) {        fireLifecycleEvent(lifecycleEvent, data);    }}

监听机制

事件监听器须要三个参与者:

  • 事件对象—用于封装事件的信息,在事件监听器接口的对立办法中作为参数,个别继承 java.util.EventObjecct类。
  • 事件源—触发事件对的源头,不同事件源触发不同事件。
  • 事件监听器—负责监听事件源收回的事件,产生事件时,事件源调用事件监听器的对立办法解决。监听器个别实现java.util.EventListener接口。
COPYpublic final class LifecycleEvent extends java.util.EventObject {    public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {        super(lifecycle);        this.type = type;        this.data = data;    }}COPYpublic interface LifecycleListener {    public void lifecycleEvent(LifecycleEvent event);}COPYpublic class HostConfig implements LifecycleListener {    @Override    public void lifecycleEvent(LifecycleEvent event) {        try {            host = (Host) event.getLifecycle();            if (host instanceof StandardHost) {                setCopyXML(((StandardHost) host).isCopyXML());                setDeployXML(((StandardHost) host).isDeployXML());                setUnpackWARs(((StandardHost) host).isUnpackWARs());                setContextClass(((StandardHost) host).getContextClass());            }        } catch (ClassCastException e) {            return;        }        // Process the event that has occurred        if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) {            check();        } else if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {            beforeStart();        } else if (event.getType().equals(Lifecycle.START_EVENT)) {            start();        } else if (event.getType().equals(Lifecycle.STOP_EVENT)) {            stop();        }    }}COPY// LifecycleBase.startInternalthis.state = state;String lifecycleEvent = state.getLifecycleEvent();if (lifecycleEvent != null) {    fireLifecycleEvent(lifecycleEvent, data);}protected void fireLifecycleEvent(String type, Object data) {    LifecycleEvent event = new LifecycleEvent(this, type, data);    for (LifecycleListener listener : lifecycleListeners) {        listener.lifecycleEvent(event);    }}

模板办法

四个模板办法,由子类具体实现
COPYprotected abstract void initInternal() throws LifecycleException;protected abstract void startInternal() throws LifecycleException;protected abstract void stopInternal() throws LifecycleException;protected abstract void destroyInternal() throws LifecycleException;

总结

通过提供init、start、stop、destory办法,通过相应的模板办法【模板设计模式】,提供组件的对立生命周期的治理、事件调度。

本文由传智教育博学谷狂野架构师教研团队公布。

如果本文对您有帮忙,欢送关注点赞;如果您有任何倡议也可留言评论私信,您的反对是我保持创作的能源。

转载请注明出处!