关于java:你可能不那么知道的Tomcat生命周期管理-博学谷狂野架构师

7次阅读

共计 10493 个字符,预计需要花费 27 分钟才能阅读完成。

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<>();

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

// 子类依据以后状态触发不同事件,实现不同操作
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@Override
public 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@Override
public 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@Override
public 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@Override
public 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.startInternal
this.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 办法,通过相应的模板办法【模板设计模式】,提供组件的对立生命周期的治理、事件调度。

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

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

转载请注明出处!

正文完
 0