Tomcat 源码阅读Lifecycle

Posted 皓月行空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat 源码阅读Lifecycle相关的知识,希望对你有一定的参考价值。

环境:tomcat7.0.28

坚持一下,把源码看完,勤奋一点,不要在懒惰了,你已经落下别人很多了

本文主要介绍Tomcat的生命周期模型 Lifecycle

一、Lifecycle介绍

1、Lifecycle的状态枚举类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),
    /**
     * @deprecated Unused. Will be removed in Tomcat 9.0.x. The state transition
     *             checking in @link org.apache.catalina.util.LifecycleBase
     *             makes it impossible to use this state. The intended behaviour
     *             can be obtained by setting the state to
     *             @link LifecycleState#FAILED in
     *             <code>LifecycleBase.startInternal()</code>
     */
    @Deprecated
    MUST_STOP(true, null),
    /**
     * @deprecated Unused. Will be removed in Tomcat 9.0.x. The state transition
     *             checking in @link org.apache.catalina.util.LifecycleBase
     *             makes it impossible to use this state. The intended behaviour
     *             can be obtained by implementing @link Lifecycle.SingleUse.
     */
    @Deprecated
    MUST_DESTROY(false, null);

    private final boolean available;//
    private final String lifecycleEvent;

    private 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>
     * <li>@link #MUST_STOP</li>
     * </ul>
     */
    public boolean isAvailable() 
        return available;
    

    /**
     *
     */
    public String getLifecycleEvent() 
        return lifecycleEvent;
    


2、Lifecycle接口定义

public interface Lifecycle 


    // ----------------------------------------------------- Manifest Constants

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


    // --------------------------------------------------------- Public Methods


    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 interface SingleUse 
    


3、lifecycle生命周期流程图



二、LifecycleBase 介绍

LifecycleBase  是Lifecycle接口的抽象实现类。

1、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);
        
    
该方法用于组件设置生命周期状态的时候进行状态的检查,并且触发生命周期事件。如果是不合理的状态之间进行切换,则会抛出异常。

重点来看函数fireLifecycleEvent

2、LifecycleBase.fireLifecycleEvent

 protected void fireLifecycleEvent(String type, Object data) 
        lifecycle.fireLifecycleEvent(type, data);
    
private LifecycleSupport lifecycle = new LifecycleSupport(this);

LifecycleSupport.fireLifecycleEvent方法:

    public void fireLifecycleEvent(String type, Object data) 

        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = listeners;
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);

    

当改变Lifecycle的子类的生命周期状态的时候,会触发生命周期事件,也就是LifecycleEvent,最终会调用LifecycleListener的lifecycleEvent事件。

listeners 是一个数组,在LifecycleSupport中定义了一个线程安全的addLifecycleListener 的方法,实现逻辑是 “写时复制”。

3、LifecycleBase.init 和 start方法解析

    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;

    /**
     * @inheritDoc
     */
    @Override
    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.
            ExceptionUtils.handleThrowable(t);
            setStateInternal(LifecycleState.FAILED, null, false);
            throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t);
        
    


    /**
     * Sub-classes must ensure that the state is changed to
     * @link LifecycleState#STARTING during the execution of this method.
     * Changing state will trigger the @link Lifecycle#START_EVENT event.
     *
     * If a component fails to start it may either throw a
     * @link LifecycleException which will cause it's parent to fail to start
     * or it can place itself in the error state in which case @link #stop()
     * will be called on the failed component but the parent component will
     * continue to start normally.
     *
     * @throws LifecycleException
     */
    protected abstract void startInternal() throws LifecycleException;

通过LifecycleBase 的init 方法可以看出,在任何生命周期组件的初始化过程中,都需要先设置组件的生命周期状态为初始化正在进行的状态,调用初始化中状态事件,然后调用初始化方法,最后再设置一下初始化完毕的状态,调用完毕状态的事件。




以上是关于Tomcat 源码阅读Lifecycle的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat9.0--入门篇1

Android jetpack架构组件Lifecycle实战与源码解析

Tomcat源码阅读(初窥)

Tomcat 8解读Tomcat组件的生命周期(Lifecycle)

不看lifecycle源码,认真聊聊它的实现原理

不看lifecycle源码,认真聊聊它的实现原理