tomcat生命周期 - 969251639/study GitHub Wiki

1. Tomcat的生命周期类图:

上面最重要的两个类是LifecycleBase和它的实现类LifecycleMBeanBase,LifecycleBase定义生命周期的基本操作,LifecycleMBeanBase则是操作MBean的类,Lifecycle接口定义了tomcat生命周期的状态和常用的操作方法,LifecycleSupport则提供了操作生命周期的工具类

public interface Lifecycle {
    //初始化之前状态
    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 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;
    //获取当前状态
    public LifecycleState getState();
    //获取当前状态名
    public String getStateName();
}

public final class LifecycleSupport {

    // ----------------------------------------------------------- Constructors

    //构造方法
    public LifecycleSupport(Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
    }


    // ----------------------------------------------------- Instance Variables

    private final Lifecycle lifecycle;
    //用来保存监听器的集合
    private final List<LifecycleListener> listeners = new CopyOnWriteArrayList<>();


    // --------------------------------------------------------- Public Methods
    
    //添加到监听器
    public void addLifecycleListener(LifecycleListener listener) {
        listeners.add(listener);
    }
    //从查找所有监听器
    public LifecycleListener[] findLifecycleListeners() {
        return listeners.toArray(new LifecycleListener[0]);
    }
    //触发所有监听事件
    public void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        for (LifecycleListener listener : listeners) {
            listener.lifecycleEvent(event);
        }
    }
    //移除监听器
    public void removeLifecycleListener(LifecycleListener listener) {
        listeners.remove(listener);
    }
}

在操作生命周期的方法时,都是通过重写父类的操作来完成,父类只是完成操作前操作后的架子调用,比如下面的init方法(这里的负类是指LifecycleBase)

LifecycleBase:

    @Override
    public final synchronized void init() throws LifecycleException {
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }

        try {
            //开始之前
            setStateInternal(LifecycleState.INITIALIZING, null, false);
            //真正要执行的逻辑
            initInternal();
            //开始之后
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            setStateInternal(LifecycleState.FAILED, null, false);
            throw new LifecycleException(
                    sm.getString("lifecycleBase.initFail",toString()), t);
        }
    }
    //抽象方法,子类重写
    protected abstract void initInternal() throws LifecycleException;

StandardServer:

    @Override
    protected void initInternal() throws LifecycleException {

        super.initInternal();

        // Register global String cache
        // Note although the cache is global, if there are multiple Servers
        // present in the JVM (may happen when embedding) then the same cache
        // will be registered under multiple names
        onameStringCache = register(new StringCache(), "type=StringCache");

        // Register the MBeanFactory
        MBeanFactory factory = new MBeanFactory();
        factory.setContainer(this);
        onameMBeanFactory = register(factory, "type=MBeanFactory");

        // Register the naming resources
        globalNamingResources.init();

        // Populate the extension validator with JARs from common and shared
        // class loaders
        if (getCatalina() != null) {
            ClassLoader cl = getCatalina().getParentClassLoader();
            // Walk the class loader hierarchy. Stop at the system class loader.
            // This will add the shared (if present) and common class loaders
            while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
                if (cl instanceof URLClassLoader) {
                    URL[] urls = ((URLClassLoader) cl).getURLs();
                    for (URL url : urls) {
                        if (url.getProtocol().equals("file")) {
                            try {
                                File f = new File (url.toURI());
                                if (f.isFile() &&
                                        f.getName().endsWith(".jar")) {
                                    ExtensionValidator.addSystemResource(f);
                                }
                            } catch (URISyntaxException e) {
                                // Ignore
                            } catch (IOException e) {
                                // Ignore
                            }
                        }
                    }
                }
                cl = cl.getParent();
            }
        }
        // Initialize our defined Services
        for (int i = 0; i < services.length; i++) {
            services[i].init();
        }
    }

在父类LifecycleBase中也还有其他的类似行为,比如start,stop等都类似,另外在事件状态变动时都会调用fireLifecycleEvent方法进行事件分发,比如上面的LifecycleBase类中的setStateInternal方法

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

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("lifecycleBase.setState", this, state));
        }

        if (check) {
            // Must have been triggered by one of the abstract methods (assume
            // code in this class is correct)
            // null is never a valid state
            if (state == null) {
                invalidTransition("null");
                // Unreachable code - here to stop eclipse complaining about
                // a possible NPE further down the method
                return;
            }

            // Any method can transition to failed
            // startInternal() permits STARTING_PREP to STARTING
            // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
            // STOPPING
            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))) {
                // No other transition permitted
                invalidTransition(state.name());
            }
        }

        this.state = state;//变更事件状态
        String lifecycleEvent = state.getLifecycleEvent();
        if (lifecycleEvent != null) {//调用所有监听器中的监听该事件的方法
            fireLifecycleEvent(lifecycleEvent, data);
        }
    }

2. Tomcat目前的主要生命周期状态:
NEW:容器刚刚创建时,即在LifecycleBase实例构造完成时的状态。
INITIALIZED:容器初始化完成时的状态。
STARTING_PREP:容器启动前的状态。
STARTING:容器启动过程中的状态。
STARTED:容器启动完成的状态。
STOPPING_PREP:容器停止前的状态。
STOPPING:容器停止过程中的状态。
STOPPED:容器停止完成的状态。
DESTROYED:容器销毁后的状态。
FAILED:容器启动、停止过程中出现异常的状态。

Tomcat的每个容器都会有自身的生命周期,其中也涉及状态的迁移,以及伴随的事件生成,本节详细介绍Tomcat中的容器生命周期实现。所有容器的转态转换(如新疆、初始化、启动、停止等)都是由外到内,由上到下进行,即先执行父容器的状态转换及相关操作,然后再执行子容器的转态转换,这个过程是层层迭代执行的。

3. Tomcat init时序图

4. Tomcat start时序图