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

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

[[375502]]

本文转载自微信公众号「Java极客技术」,作者鸭血粉丝 。转载本文请联系Java极客技术公众号。  

序言

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 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

大家看到这个启动过程之后,在联想一下之前的文章中的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"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

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

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

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

void addLifecycleListener(LifecycleListener var1); 
 
LifecycleListener[] findLifecycleListeners(); 
 
void removeLifecycleListener(LifecycleListener var1); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

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

4个生命周期

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

void init() throws LifecycleException; 
 
void start() throws LifecycleException; 
 
void stop() throws LifecycleException; 
 
void destroy() throws LifecycleException; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

2个获取状态的方法

LifecycleState getState(); 
 
String getStateName(); 
  • 1.
  • 2.
  • 3.

毕竟这个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; 
    } 
   } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

在这里我们还要注意一下这个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; 
            } 
        } 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.

话不多说,我们继续往下,它的生命周期方法又是什么呢?这才是今天的重点。之前我们就说生命周期包含了哪些内容,从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)nullfalse); 
           //执行方法 
           this.initInternal(); 
           //设置生命周期状态为INITIALIZED 
           this.setStateInternal(LifecycleState.INITIALIZED, (Object)nullfalse); 
       } catch (Throwable var2) { 
           ExceptionUtils.handleThrowable(var2); 
           this.setStateInternal(LifecycleState.FAILED, (Object)nullfalse); 
           throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[]{this.toString()}), var2); 
       } 
   } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

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)nullfalse); 
               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)nullfalse); 
               } 
 
           } catch (Throwable var2) { 
               ExceptionUtils.handleThrowable(var2); 
               this.setStateInternal(LifecycleState.FAILED, (Object)nullfalse); 
               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()})); 
           } 
 
       } 
   } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.

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)nullfalse); 
                   } 
                   this.stopInternal(); 
                   if (!this.state.equals(LifecycleState.STOPPING) && !this.state.equals(LifecycleState.FAILED)) { 
                       this.invalidTransition("after_stop"); 
                   } 
                   this.setStateInternal(LifecycleState.STOPPED, (Object)nullfalse); 
               } catch (Throwable var5) { 
                   ... 
               } finally { 
                  ... 
               } 
 
           } 
       } else { 
           ... 
       } 
   } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

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)nullfalse); 
                this.destroyInternal(); 
                this.setStateInternal(LifecycleState.DESTROYED, (Object)nullfalse); 
            } catch (Throwable var2) { 
                ExceptionUtils.handleThrowable(var2); 
                this.setStateInternal(LifecycleState.FAILED, (Object)nullfalse); 
                throw new LifecycleException(sm.getString("lifecycleBase.destroyFail", new Object[]{this.toString()}), var2); 
            } 
        } else { 
         ... 
        } 
    } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

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

总结

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

 

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

文献参考

 

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

 

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2021-05-27 09:30:51

Java流程控制

2021-01-07 07:33:06

Tomcat启动工具

2022-10-10 08:47:49

ITCIO数据

2021-02-19 10:14:49

云计算公共云

2021-05-08 13:11:58

物联网IOT物联网技术

2021-11-29 07:42:44

CSS 技巧CSS 绘图技巧

2014-04-08 09:56:30

销售易CRM

2020-11-04 11:17:20

好代码程序员整洁

2024-03-04 09:19:33

CSSbackground前端

2015-07-08 16:28:23

weak生命周期

2024-08-30 10:40:12

2023-12-08 13:16:00

CSSJSXStyleX

2018-01-16 15:02:20

存储RAIDSAN

2023-02-17 14:40:06

物联网供应链

2012-10-29 15:45:51

2021-10-04 15:46:31

网络通信5G

2021-03-24 15:25:44

AI

2021-09-30 19:12:46

通信网络ADSL

2022-11-18 10:17:10

点赞
收藏

51CTO技术栈公众号