2

面试官:既然启动流程不太了解,那你知道Tomcat的生命周期是什么样子的么?

 3 years ago
source link: http://www.justdojava.com/2021/01/08/Tomcat/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

上一次的文章中,阿粉在面试官面前说了对启动流程不太理解,然后和他聊了一会,然后他又提出了你既然不是特别了解启动流程的话,那你对Tomcat的生命周期熟悉么?

Tomcat的生命周期管理的话,我们不能总是从书中获取那些知识,而是结合实践,然后综合书中的内容,进行一层一层的深入分析,这样对自己记忆和理解都能更加的透彻。

启动的时候的

大家可以随便找一个zip版本的Tomcat,然后直接启动起来,我们来看看是个什么样子的,

一月 11, 2021 10:16:24 上午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-bio-8080"]
一月 11, 2021 10:16:24 上午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
一月 11, 2021 10:16:24 上午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 470 ms
一月 11, 2021 10:16:24 上午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
一月 11, 2021 10:16:24 上午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.88
一月 11, 2021 10:16:24 上午 org.apache.catalina.startup.HostConfig deployDirectory

大家看到这个启动过程之后,在联想一下之前的文章中的Tomcat的启动流程,是不是又感觉有点那个味道了,load,然后start,最后然后stop了。

划重点1: Lifecycle

在之前的文章中,我们提到了Lifecycle, 而Tomcat也就是通过Lifecycle接口统一管理生命周期,所有有生命周期的组件都要实现Lifecycle接口,以便提供一致的机制去启动和停止组件。

那么我们就来分析一下这个Lifecycle接口里面都包含了哪些内容,大家可以直接去tomcat的包中的catalina的jar下面去寻找看一下,

  • 定义了13个String类型的变量

  • 定义了3个管理监听器的方法

  • 定义了4个生命周期

  • 定义了2个获取当前状态的方法

那么我们先说这个13个变量:

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

这13个变量是什么意思呢?在《Tomcat架构解析》一书中说到,这些常量信息用于LifecycleEvent事件的type属性中,作用是区分组件发出的LifecycleEvent事件时的状态(如初始化前、启动前、启动中等)。这种设计方法可以让多种状态都发送同一种类型的时间,然后用其中的一个属性类区分状态而不用定义多种事件。

其实大家可以根据变量的名字就能看出来,初始化前,初始化后,启动,启动前,启动后。。。。说的在直白一点 ,就是为了表示组件发出时的状态而已。

而三个管理监听的方法又是什么呢?

void addLifecycleListener(LifecycleListener var1);

LifecycleListener[] findLifecycleListeners();

void removeLifecycleListener(LifecycleListener var1);

而这个三个监听器也分别就是用来添加,查找和删除LifecycleListener类型的监听器。这里面是三个接口,具体实现一会我们去子类里面找,在这里先知道有这么个东西就行,下面就会直接分析。

4个生命周期

这个就肯定很简单了,比如像我们都知道在Servlet的生命周期一样,init,start,stop,destroy,初始化,启动,停止,销毁,

void init() throws LifecycleException;

void start() throws LifecycleException;

void stop() throws LifecycleException;

void destroy() throws LifecycleException;

2个获取状态的方法

LifecycleState getState();

String getStateName();

毕竟这个Lifecycle是一个接口,它并不是具体的实现类,我们想要了解这个,那么就一定得去具体的实现类里面去找寻这个内容,那么他的实现类是什么呢?来了来了,它来了,LifecycleBase

LifecycleBase

LifecycleBase是抽象类,是tomcat中所有组件类的基类,他实现了Lifecycle,但是Tomcat下的很多子类也同样的继承了它,所以他也是非常重要的,

public abstract class LifecycleBase implements Lifecycle {
 private LifecycleSupport lifecycle = new LifecycleSupport(this);
 // 源组件的当前状态,不同状态触发不同事件
    private volatile LifecycleState state;
    public LifecycleBase() {
        this.state = LifecycleState.NEW;
    }
   }

在这里我们还要注意一下这个LifecycleSupport类,LifecycleSupport中定义了一个LifecycleListener数组类型的属性来保存所有的监听器,然后在里面分别定义了添加,删除,查找,执行监听器的方法,不信的话,我们来看看,毕竟这个类放在这里先new出来也是有一定道理的。

public final class LifecycleSupport {
    private Lifecycle lifecycle = null;
    private LifecycleListener[] listeners = new LifecycleListener[0];
    private final Object listenersLock = new Object();

    public LifecycleSupport(Lifecycle lifecycle) {
        this.lifecycle = lifecycle;
    }

    public void addLifecycleListener(LifecycleListener listener) {
        Object var2 = this.listenersLock;
        synchronized(this.listenersLock) {
            LifecycleListener[] results = new LifecycleListener[this.listeners.length + 1];

            for(int i = 0; i < this.listeners.length; ++i) {
                results[i] = this.listeners[i];
            }

            results[this.listeners.length] = listener;
            this.listeners = results;
        }
    }

    public LifecycleListener[] findLifecycleListeners() {
        return this.listeners;
    }

    public void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this.lifecycle, type, data);
        LifecycleListener[] interested = this.listeners;

        for(int i = 0; i < interested.length; ++i) {
            interested[i].lifecycleEvent(event);
        }

    }

    public void removeLifecycleListener(LifecycleListener listener) {
        Object var2 = this.listenersLock;
        synchronized(this.listenersLock) {
            int n = -1;

            for(int i = 0; i < this.listeners.length; ++i) {
                if (this.listeners[i] == listener) {
                    n = i;
                    break;
                }
            }

            if (n >= 0) {
                LifecycleListener[] results = new LifecycleListener[this.listeners.length - 1];
                int j = 0;

                for(int i = 0; i < this.listeners.length; ++i) {
                    if (i != n) {
                        results[j++] = this.listeners[i];
                    }
                }

                this.listeners = results;
            }
        }
    }
}

话不多说,我们继续往下,它的生命周期方法又是什么呢?这才是今天的重点。之前我们就说生命周期包含了哪些内容,从init开始,然后start,然后stop以及最后的destroy方法,在实现类里面表现的那是淋漓尽致。

init方法

 public final synchronized void init() throws LifecycleException {
        //这里表示只有NEW状态下是可以使用的,
        if (!this.state.equals(LifecycleState.NEW)) {
            this.invalidTransition("before_init");
        }
    //在这里通过不同的状态,然后去触发不同的事件,
        try {
            //设置生命周期状态为INITIALIZING
            this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false);
            //执行方法
            this.initInternal();
            //设置生命周期状态为INITIALIZED
            this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false);
        } catch (Throwable var2) {
            ExceptionUtils.handleThrowable(var2);
            this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
            throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[]{this.toString()}), var2);
        }
    }

start方法

    public final synchronized void start() throws LifecycleException {
    //在这里验证生命周期状态,状态是这三种状态的是为不可用状态STARTING_PREP,STARTING,STARTED
        if (!LifecycleState.STARTING_PREP.equals(this.state) && !LifecycleState.STARTING.equals(this.state) && !LifecycleState.STARTED.equals(this.state)) {
            //如果是NEW状态,执行init方法
            if (this.state.equals(LifecycleState.NEW)) {
                this.init();
            //如果是FAILED状态,那么执行stop方法
            } else if (this.state.equals(LifecycleState.FAILED)) {
                this.stop();
            //如果是INITIALIZED状态,那么就会告诉你是个非法的操作
            } else if (!this.state.equals(LifecycleState.INITIALIZED) && !this.state.equals(LifecycleState.STOPPED)) {
                this.invalidTransition("before_start");
            }

            try {
                //设置启动状态为 STARTING_PREP
                this.setStateInternal(LifecycleState.STARTING_PREP, (Object)null, false);
                this.startInternal();
                //这里就非常的严谨,他会在启动之后,继续去看状态是什么,保证启动成功
                if (this.state.equals(LifecycleState.FAILED)) {
                    this.stop();
                } else if (!this.state.equals(LifecycleState.STARTING)) {
                    this.invalidTransition("after_start");
                } else {
                    this.setStateInternal(LifecycleState.STARTED, (Object)null, false);
                }

            } catch (Throwable var2) {
                ExceptionUtils.handleThrowable(var2);
                this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
                throw new LifecycleException(sm.getString("lifecycleBase.startFail", new Object[]{this.toString()}), var2);
            }
        } else {
            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", new Object[]{this.toString()}), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", new Object[]{this.toString()}));
            }

        }
    }

stop方法

 public final synchronized void stop() throws LifecycleException {
        //同样的,和上面一样,三种状态下不可执行
        if (!LifecycleState.STOPPING_PREP.equals(this.state) && !LifecycleState.STOPPING.equals(this.state) && !LifecycleState.STOPPED.equals(this.state)) {
            //如果是NEW状态,状态直接修改为STOPPED
            if (this.state.equals(LifecycleState.NEW)) {
                this.state = LifecycleState.STOPPED;
            } else {
                //如果不是这2中状态,那么就直接异常
                if (!this.state.equals(LifecycleState.STARTED) && !this.state.equals(LifecycleState.FAILED)) {
                    this.invalidTransition("before_stop");
                }
                try {
                    if (this.state.equals(LifecycleState.FAILED)) {
                        this.fireLifecycleEvent("before_stop", (Object)null);
                    } else {
                        this.setStateInternal(LifecycleState.STOPPING_PREP, (Object)null, false);
                    }
                    this.stopInternal();
                    if (!this.state.equals(LifecycleState.STOPPING) && !this.state.equals(LifecycleState.FAILED)) {
                        this.invalidTransition("after_stop");
                    }
                    this.setStateInternal(LifecycleState.STOPPED, (Object)null, false);
                } catch (Throwable var5) {
                    ...
                } finally {
                   ...
                }

            }
        } else {
            ...
        }
    }

destroy方法

public final synchronized void destroy() throws LifecycleException {
        //如果状态是启动失败的,也就是FAILED,那么会直接去调用stop方法,
        if (LifecycleState.FAILED.equals(this.state)) {
            try {
                this.stop();
            } catch (LifecycleException var3) {
                log.warn(sm.getString("lifecycleBase.destroyStopFail", new Object[]{this.toString()}), var3);
            }
        }
        //如果是这两种状态DESTROYING、DESTROYED,那么就不再进行执行了,直接进行return
        if (!LifecycleState.DESTROYING.equals(this.state) && !LifecycleState.DESTROYED.equals(this.state)) {
            if (!this.state.equals(LifecycleState.STOPPED) && !this.state.equals(LifecycleState.FAILED) && !this.state.equals(LifecycleState.NEW) && !this.state.equals(LifecycleState.INITIALIZED)) {
                this.invalidTransition("before_destroy");
            }

            try {
                this.setStateInternal(LifecycleState.DESTROYING, (Object)null, false);
                this.destroyInternal();
                this.setStateInternal(LifecycleState.DESTROYED, (Object)null, false);
            } catch (Throwable var2) {
                ExceptionUtils.handleThrowable(var2);
                this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
                throw new LifecycleException(sm.getString("lifecycleBase.destroyFail", new Object[]{this.toString()}), var2);
            }
        } else {
         ...
        }
    }

阿粉在其中精简了一些代码,如果大家有兴趣的可以自己去翻一下源码,然后自己去看一下,这样对比出来才有效果。

其实就是通过不同的状态转变,然后相应的去调用init、start、stop、destroy方法,然后提供所有Tomcat组件的生命周期管理。

10.jpg

上图就是接口状态不同情况执行不同方法的图,图片来自《Tomcat架构解析》

文献参考

《深入剖析Tomcat》 《Tomcat架构解析》 《Servlet/JSP深入详解》


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK