您的位置:首页 > 运维架构 > Tomcat

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

2017-07-01 20:38 507 查看
转载请注明出处: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
组件的状态转换图如下。



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


每个实现组件都继承自
LifecycleBase
LifecycleBase
实现了
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) {
// 省略代码
}
}
}


主要步骤如下:

新建
Bootstrap
对象
daemon
,并调用其
init()
方法

初始化Tomcat的类加载器

用反射实例化
org.apache.catalina.startup.Catalina
对象
catalinaDaemon


调用
daemon
load
方法,实质上调用了
catalinaDaemon
load
方法

加载和解析server.xml配置文件

调用
daemon
start
方法,实质上调用了
catalinaDaemon
start
方法

启动
Server
组件,
Server
的启动会带动其他组件的启动,如
Service
,
Container
,
Connector


调用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) {
// 省略代码
}
}
}


新建
Bootstrap
对象
daemon
,并调用其
init()
方法

初始化Tomcat的类加载器

用反射实例化
org.apache.catalina.startup.Catalina
对象
catalinaDaemon


调用
daemon
stopServer
方法,实质上调用了
catalinaDaemon
stopServer
方法

解析
server.xml
文件,构造出Server容器

获取Server的socket监听端口和地址,创建Socket对象连接启动Tomcat时创建的ServerSocket,最后向ServerSocket发送
SHUTDOWN
命令

运行中的Server调用
stop
方法停止

5 总结



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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: