欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Tomcat9源码分析】生命周期、启动、停止概述

程序员文章站 2024-03-25 16:12:22
...

转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73350812


1 前言

在Tomcat启动时,会读取server.xml文件创建Server, Service, Connector, Engine, Host, Context, Wrapper等组件,各个组件的介绍可以参考Tomcat组件与框架

各组件创建完成后,Tomcat负责管理它们的生命周期,本文先介绍Tomcat中的组件生命周期管理,然后再介绍Tomcat的启动与停止。


2 生命周期管理

2.1 Lifecycle

Tomcat中的所有组件都继承了Lifecycle接口,Lifecycle接口定义了一整套生命周期管理的函数,从组件的新建、初始化完成、启动、停止、失败到销毁,都遵守同样的规则,Lifecycle组件的状态转换图如下。


【Tomcat9源码分析】生命周期、启动、停止概述
Lifecycle状态转移图

Lifecycle接口的主要方法如下,正常的调用顺序是init()->start()->destroy(),父组件的init()start()会触发子组件的init()start(),所以Tomcat中只需调用Server组件的init()start()即可。

public interface Lifecycle {

    public void init() throws LifecycleException;

    public void start() throws LifecycleException;

    public void stop() throws LifecycleException;

    public void destroy() throws LifecycleException;

    public LifecycleState getState();

    public void addLifecycleListener(LifecycleListener listener);

    public LifecycleListener[] findLifecycleListeners();

    public void removeLifecycleListener(LifecycleListener listener);
}

每个实现组件都继承自LifecycleBaseLifecycleBase实现了Lifecycle接口,当容器状态发生变化时,都会调用fireLifecycleEvent方法,生成LifecycleEvent,并且交由此容器的事件监听器处理。

public abstract class LifecycleBase implements Lifecycle {

    protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            listener.lifecycleEvent(event);
        }
    }
}

2.2 LifecycleListener与LifecycleEvent

Lifecycle接口中,还看到LifecycleListener,这是用来监听Lifecycle发生的事件,LifecycleListener接口只定义了一个回调函数。

public interface LifecycleListener {

    /**
     * Acknowledge the occurrence of the specified event.
     *
     * @param event LifecycleEvent that has occurred
     */
    public void lifecycleEvent(LifecycleEvent event);

}

3 Tomcat启动

下面来看看在执行tomcat/bin/startup.sh脚本后发生了什么事。执行该脚本等价于执行org.apache.catalina.startup.Bootstra类的main方法,并传入start参数。

package org.apache.catalina.startup;

public final class Bootstrap {

    public static void main(String args[]) {

        if (daemon == null) {
            Bootstrap bootstrap = new Bootstrap();
            try {
                // 1 调用Bootstrap类的init方法
                bootstrap.init();
            } catch (Throwable t) {
                // 省略代码
            }
            daemon = bootstrap;
        } else {
            // 省略代码
        }

        try {
            String command = "start";

            // 省略代码

            if (command.equals("start")) {
                daemon.setAwait(true);

                // 2 调用Bootstrap类的load方法
                daemon.load(args);

                // 3 调用Bootstrap类的load方法
                daemon.start();
            } 
        } catch (Throwable t) {
            // 省略代码
        }
    }
}

主要步骤如下:

  1. 新建Bootstrap对象daemon,并调用其init()方法
    1. 初始化Tomcat的类加载器
    2. 用反射实例化org.apache.catalina.startup.Catalina对象catalinaDaemon
  2. 调用daemonload方法,实质上调用了catalinaDaemonload方法
    1. 加载和解析server.xml配置文件
  3. 调用daemonstart方法,实质上调用了catalinaDaemonstart方法
    1. 启动Server组件,Server的启动会带动其他组件的启动,如Service, Container, Connector
    2. 调用catalinaDaemon的await方法循环等待接收Tomcat的shutdown命令

4 Tomcat停止

启动部分最后介绍了catalinaDaemon调用await等待停止命令,我们一般是通过执行tomcat/bin/shutdown.sh来关闭Tomcat,等价于执行org.apache.catalina.startup.Bootstra类的main方法,并传入stop参数。

package org.apache.catalina.startup;

public final class Bootstrap {

    public static void main(String args[]) {

        if (daemon == null) {
            Bootstrap bootstrap = new Bootstrap();
            try {
                // 1 调用Bootstrap类的init方法
                bootstrap.init();
            } catch (Throwable t) {
                // 省略代码
            }
            daemon = bootstrap;
        } else {
            // 省略代码
        }

        try {
            String command = "start";

            // 省略代码

            if (command.equals("stop")) {
                // 2 调用Bootsrap类的stopServer方法
                daemon.stopServer(args);
            } 
        } catch (Throwable t) {
            // 省略代码
        }
    }
}
  1. 新建Bootstrap对象daemon,并调用其init()方法
    1. 初始化Tomcat的类加载器
    2. 用反射实例化org.apache.catalina.startup.Catalina对象catalinaDaemon
  2. 调用daemonstopServer方法,实质上调用了catalinaDaemonstopServer方法
    1. 解析server.xml文件,构造出Server容器
    2. 获取Server的socket监听端口和地址,创建Socket对象连接启动Tomcat时创建的ServerSocket,最后向ServerSocket发送SHUTDOWN命令
    3. 运行中的Server调用stop方法停止

5 总结


【Tomcat9源码分析】生命周期、启动、停止概述
Tomcat启动与关闭流程


6 参考

http://tomcat.apache.org/tomcat-9.0-doc/architecture/startup/serverStartup.txt
http://tomcat.apache.org/tomcat-9.0-doc/architecture/startup/serverStartup.pdf
http://blog.csdn.net/beliefer/article/details/51585006


转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73350812

相关标签: tomcat 源码