Tomcat9.0的生命周期

生命周期接口

Tomcat拥有很多组件,假如在启动Tomcat时一个一个组件启动,这不仅麻烦而且容易遗漏组件,还会对后面的动态组件扩展带来麻烦。对于这个问题,Tomcat用Lifecycle管理启动、停止、关闭。

Tomcat内部架构中,Server包含Service, Service包含Container和Connector,往下再一层层包含。Tomcat就是以容器的方式来组织整个系统架构的,可以通过父容器启动它的子容器,这样只要启动根容器,即可把其他所有容器都启动,达到统一启动、停止、关闭的效果。

作为统一的接口,Lifecycle把所有的启动、停止、关闭、生命周期相关的方法都组织到一起,就可以很方便地管理Tomcat各个容器组件的生命周期。下面是Lifecycle接口详细的定义。

public interface Lifecycle {

    String BEFORE_INIT_EVENT = "before_init";

    String AFTER_INIT_EVENT = "after_init";

    String START_EVENT = "start";

    String BEFORE_START_EVENT = "before_start";

    String AFTER_START_EVENT = "after_start";

    String STOP_EVENT = "stop";

    String BEFORE_STOP_EVENT = "before_stop";

    String AFTER_STOP_EVENT = "after_stop";

    String AFTER_DESTROY_EVENT = "after_destroy";

    String BEFORE_DESTROY_EVENT = "before_destroy";

    String PERIODIC_EVENT = "periodic";

    String CONFIGURE_START_EVENT = "configure_start";

    String CONFIGURE_STOP_EVENT = "configure_stop";

    void addLifecycleListener(LifecycleListener listener);

    LifecycleListener[] findLifecycleListeners();

    void removeLifecycleListener(LifecycleListener listener);

    void init() throws LifecycleException;

    void start() throws LifecycleException;

    void stop() throws LifecycleException;

    void destroy() throws LifecycleException;

    LifecycleState getState();

    String getStateName();

    /**
     * Marker interface used to indicate that the instance should only be used
     * once. Calling {@link #stop()} on an instance that supports this interface
     * will automatically call {@link #destroy()} after {@link #stop()}
     * completes.
     */
    interface SingleUse {
    }
}

从上面可以看出,Lifecycle其实就定义了一些状态常量和几个方法,例如:init、start、stop等方法,所有需要被生命周期管理的容器都要实现这个接口,并且各自被父容器的相应方法调用。例如,在初始化阶段,根容器Server组件会调用init方法,而在init方法里会调用它的子容器Service组件的init方法,以此类推。 

生命周期的转化

Lifecycle有个返回状态的方法getState(),返回的是LifecycleState枚举类型,此枚举包含了生命周期所有的状态,供组件状态之间转换使用。

public enum LifecycleState {
    NEW(false, null),
    INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),
    INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),
    STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),
    STARTING(true, Lifecycle.START_EVENT),
    STARTED(true, Lifecycle.AFTER_START_EVENT),
    STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),
    STOPPING(false, Lifecycle.STOP_EVENT),
    STOPPED(false, Lifecycle.AFTER_STOP_EVENT),
    DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),
    DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),
    FAILED(false, null);

    private final boolean available;
    private final String lifecycleEvent;

    LifecycleState(boolean available, String lifecycleEvent) {
        this.available = available;
        this.lifecycleEvent = lifecycleEvent;
    }

    /**
     * May the public methods other than property getters/setters and lifecycle
     * methods be called for a component in this state? It returns
     * <code>true</code> for any component in any of the following states:
     * <ul>
     * <li>{@link #STARTING}</li>
     * <li>{@link #STARTED}</li>
     * <li>{@link #STOPPING_PREP}</li>
     * </ul>
     *
     * @return <code>true</code> if the component is available for use,
     *         otherwise <code>false</code>
     */
    public boolean isAvailable() {
        return available;
    }

    public String getLifecycleEvent() {
        return lifecycleEvent;
    }
}

整个生命周期内状态的转化相对较复杂,转换情况如图:

 *            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()                             |
 * ----»-----------------------------»------------------------------

生命周期事件监听机制

在这么多状态之间转换,我们会有这样的需求:在某个状态发生前后做一些工作。Tomcat使用事件监听器模式来实现这样的功能:

  • 事件对象,封装事件的信息,在事件监听器接口的统一方法中作为参数使用,继承java. util.EventObject类
  • 事件源,触发事件的源头,不同的事件源会触发不同的事件类型
  • 事件监听器,负责监听事件源发出的事件

LifecycleEvent类就是事件对象,继承了EventObject类;LifecycleListener为事件监听器接口,里面只定义了一个方法lifecycleEvent (LifecycleEvent event)。很明显,LifecycleEvent作为这个方法的参数。最后缺一个事件源,一般来说,组件和容器就是事件源。父类LifecycleBase,帮助管理该组件或容器上的监听器,里面维护了一个监听器集合,并提供了注册、移除、触发监听器等方法,这样整个监听器框架就完成了。 

 事件对象:

public final class LifecycleEvent extends EventObject {

    private static final long serialVersionUID = 1L;

    /**
     * Construct a new LifecycleEvent with the specified parameters.
     *
     * @param lifecycle Component on which this event occurred
     * @param type Event type (required)
     * @param data Event data (if any)
     */
    public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
        super(lifecycle);
        this.type = type;
        this.data = data;
    }

    /**
     * The event data associated with this event.
     */
    private final Object data;

    /**
     * The event type this instance represents.
     */
    private final String type;

    /**
     * @return the event data of this event.
     */
    public Object getData() {
        return data;
    }

    /**
     * @return the Lifecycle on which this event occurred.
     */
    public Lifecycle getLifecycle() {
        return (Lifecycle) getSource();
    }

    /**
     * @return the event type of this event.
     */
    public String getType() {
        return this.type;
    }
}

 事件监听器接口:

public interface LifecycleListener {

    /**
     * Acknowledge the occurrence of the specified event.
     *
     * @param event LifecycleEvent that has occurred
     */
    void lifecycleEvent(LifecycleEvent event);

}

 事件监听管理类LifecycleBase:

public abstract class LifecycleBase implements Lifecycle {

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

    @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);
    }

    /**
     * Allow sub classes to fire {@link Lifecycle} events.
     *
     * @param type  Event type
     * @param data  Data associated with event.
     */
    protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            listener.lifecycleEvent(event);
        }
    }

    protected synchronized void setState(LifecycleState state) throws LifecycleException {
        setStateInternal(state, null, true);
    }

    private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)
            throws LifecycleException {

        ...

        this.state = state;
        String lifecycleEvent = state.getLifecycleEvent();
        if (lifecycleEvent != null) {
            fireLifecycleEvent(lifecycleEvent, data);
        }
    }
}

事件源,例如StandardSever类,开启的时候,调用setState()方法设置状态,继续调用到LifecycleBase.setStateInternal()方法,最后就会让相关监听器进行处理:

public final class StandardServer extends LifecycleMBeanBase implements Server {

    /**
     * Global naming resources.
     */
    private NamingResourcesImpl globalNamingResources = null;

    /**
     * The naming context listener for this web application.
     */
    private final NamingContextListener namingContextListener;

    /**
     * Start nested components ({@link Service}s) and implement the requirements of
     * {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
     *
     * @exception LifecycleException if this component detects a fatal error that prevents this component from being
     *                                   used
     */
    @Override
    protected void startInternal() throws LifecycleException {
        
        ...
        
        setState(LifecycleState.STARTING);

        ...
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值