天天看點

tomcat源碼分析(一) —— 元件的生命周期管理

  • 元件之間關系?
    tomcat源碼分析(一) —— 元件的生命周期管理

    我們觀察上面的繼承圖得知,tomcat的元件都直接和間接的繼承了LifecycleMBeanBase,LifecycleBase類

    對于容器元件,我們觀察他直接繼承了ContainerBase。是以下面我們着重分析這些被繼承類都實作了哪些的通用功能。

  • LifecycleBase
    tomcat源碼分析(一) —— 元件的生命周期管理

    1.初始化

    會校驗是否為NEW狀态,若狀态錯誤,抛出異常。

    設定狀态為初始化中,并進行事件的廣播;

    設定狀态為初始化完成,并進行事件的廣播;

    tomcat源碼分析(一) —— 元件的生命周期管理

    2.啟動

    列印日志

    目前元件狀态為NEW,進行初始化init(),為FAILED狀态,執行stop().對于元件的異常狀态進行抛出異常的操作。

    設定目前元件狀态為啟動前,并進行事件廣播;

    執行元件的啟動操作;

    設定元件的啟動完成的操作,并進行事件廣播。

public final synchronized void start() throws LifecycleException {

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

        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 {
            // 設定狀态為啟動前
            setStateInternal(LifecycleState.STARTING_PREP, null, false);
            // 開始啟動
            startInternal();
            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());
        }
    }
           

3.停止

日志列印

設定目前元件狀态為停止前,執行子類的停止操作,停止完成;

public final synchronized void stop() throws LifecycleException {

        if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||
                LifecycleState.STOPPED.equals(state)) {

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

            return;
        }

        if (state.equals(LifecycleState.NEW)) {
            state = LifecycleState.STOPPED;
            return;
        }

        if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {
            invalidTransition(Lifecycle.BEFORE_STOP_EVENT);
        }

        try {
            if (state.equals(LifecycleState.FAILED)) {
                // Don't transition to STOPPING_PREP as that would briefly mark the
                // component as available but do ensure the BEFORE_STOP_EVENT is
                // fired
                fireLifecycleEvent(BEFORE_STOP_EVENT, null);
            } else {
                setStateInternal(LifecycleState.STOPPING_PREP, null, false);
            }

            stopInternal();

            // Shouldn't be necessary but acts as a check that sub-classes are
            // doing what they are supposed to.
            if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {
                invalidTransition(Lifecycle.AFTER_STOP_EVENT);
            }

            setStateInternal(LifecycleState.STOPPED, null, false);
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.stopFail", toString());
        } finally {
            if (this instanceof Lifecycle.SingleUse) {
                // Complete stop process first
                setStateInternal(LifecycleState.STOPPED, null, false);
                destroy();
            }
        }
    }
           
  • LifecycleMBeanBase

    -在元件進行初始化的時候,調用initInternal()方法,完成JMX的注冊服務。

    tomcat源碼分析(一) —— 元件的生命周期管理
tomcat源碼分析(一) —— 元件的生命周期管理
  • ContainerBase
@Override
    protected synchronized void startInternal() throws LifecycleException {

        // Start our subordinate components, if any
        Loader loader = getLoaderInternal();
        if ((loader != null) && (loader instanceof Lifecycle))
            ((Lifecycle) loader).start();
        logger = null;
        // 為standardhost初始化一個預設的日志對象
        getLogger();
        //擷取管理器
        Manager manager = getManagerInternal();
        if ((manager != null) && (manager instanceof Lifecycle))
            ((Lifecycle) manager).start(); // 啟動管理器
        Cluster cluster = getClusterInternal();
        // 叢集初始化
        if ((cluster != null) && (cluster instanceof Lifecycle))
            ((Lifecycle) cluster).start();
        // 擷取校驗對象
        Realm realm = getRealmInternal();
        if ((realm != null) && (realm instanceof Lifecycle))
            ((Lifecycle) realm).start();
        DirContext resources = getResourcesInternal();
        if ((resources != null) && (resources instanceof Lifecycle))
            ((Lifecycle) resources).start();

        // Start our child containers, if any

        // 擷取子容器,托管給線程進行啟動
        Container children[] = findChildren();
        List<Future<Void>> results = new ArrayList<Future<Void>>();
        for (int i = 0; i < children.length; i++) {
            results.add(startStopExecutor.submit(new StartChild(children[i])));
        }

        MultiThrowable multiThrowable = null;

        for (Future<Void> result : results) {
            try {
                result.get();
            } catch (Throwable e) {
                log.error(sm.getString("containerBase.threadedStartFailed"), e);
                if (multiThrowable == null) {
                    multiThrowable = new MultiThrowable();
                }
                multiThrowable.add(e);
            }

        }
        if (multiThrowable != null) {
            throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"),
                    multiThrowable.getThrowable());
        }

        // Start the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle) {
            ((Lifecycle) pipeline).start();
        }


        setState(LifecycleState.STARTING);

        // Start our thread
        threadStart();
    }
           
tomcat源碼分析(一) —— 元件的生命周期管理