Tomcat是Apache基金会的开源软件。Tomcat实现了Jakarta Servlet,Jakarta Server Pages,Jakarta Websocket,Jakarta Annotations以及 Jakarta Authentication 等规范;是一个Servlet容器,也就是说Tomcat是实现了部分J2EE规范的服务器。
Tomcat9之前都是使用的J2EE,而在Tomcat10之后全部使用JakartaEE规范。
官方网站:https://tomcat.apache.org
源代码:https://github.com/apache/tomcat
如何阅读源码
不要使用调试递进的形式进行源码研究。而是一定要利用自己的语言知识,来进行推理和阅读
模块划分之后,逐个击破,广度优先,而非深度优先,不要深究模块之间的联系
tomcat的项目结构以及目录
源码路径:
复制 /bin 二进制,大部分是执行脚本,分为linux以及windows
/conf 配置文件夹
/logs 日志路径
/res tomcat的一些资源,比如欢迎页面
/webapps 存放servlet的文件夹,默认会有管理页等
/work 工作路径,比如jsp解析完成后的servlet java文件
环境变量:
复制 CATALINA_HOME: CATALINA是Tomcat的心脏,也就是tomcat的核心引擎,该变量表示tomcat应用程序的家目录
CATALINA_BASE: 代表tomcat运行实例的目录,一台机器中可能运行多个tomcat实例,默认在tomcat的安装目录下
根据 catalina.sh start 可以最终找到启动类:org.apache.catalina.startup.Bootstrap
。
配置文件
server.xml
tomcat启动的最核心的配置文件,结构如下:
复制 <Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context />
<Context /> <!--代表一个web应用程序-->
</Host>
</Engine>
</Service>
<Service>...</Service>
</Server>
Server 元素代表tomcat服务实例,其中端口8005用于关闭服务的监听端口
Service 元素则代表一个Engine元素以及一组与之相连的Connector元素,可以有多个Service,多个Service之间的Connnector是相互隔离的。
Connector 元素是用于与客户端建立连接请求的连接器,可指定连接的端口、协议、连接超时时间等
Engine 元素是用于处理连接请求并返回响应结果的引擎,一个Engine包含多个host
Host 元素处理一个特定的host主机,一个host又有可能包含多个不同的web应用程序
Context 代表一个应用程序,一个web应用程序中又包含多个Servlet
web.xml
web.xml是Tomcat的所有的web应用的属性默认值。
logging.properties
日志配置,包含日志级别,打印格式等。
context.xml
context代表了一个web应用程序,该配置主要监听 WEB-INF下的资源,当这些资源发生变动时,立马重新加载应用。
复制 <Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
</Context>
Tomcat架构
Tomcat的整体架构是一个树形结构,每个组件负责管理自己的生命周期以及他的子组件的生命周期。
通过对该组件树进行前序遍历,可以很方便的控制父组件与其下的子组件的生命周期状态。比如要将server状态变为start,将会使用前序遍历的方式依次寻找service、connector、engine、host、context组件,当所有子组件启动后,server就完成了启动。并且,可以在这些步骤中增加Listener以监听每个组件的状态变化。
组件的生命周期管理
每个组件都实现Lifecycle接口,此接口定义了组件的主要的生命周期方法,他的定义如下,在该接口的注释中,明确定义了整个生命周期的状态机图,以及事件监听的相关方法:
复制 /**
* start()
* -----------------------------
* | |
* | init() |
* NEW -»-- INITIALIZING |
* | | | | ------------------«-----------------------
* | | |auto | | |
* | | \|/ start() \|/ \|/ auto auto stop() |
* | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
* | | | | |
* | |destroy()| | |
* | --»-----«-- ------------------------«-------------------------------- ^
* | | | |
* | | \|/ auto auto start() |
* | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
* | \|/ ^ | ^
* | | stop() | | |
* | | -------------------------- | |
* | | | | |
* | | | destroy() destroy() | |
* | | FAILED ----»------ DESTROYING ---«----------------- |
* | | ^ | |
* | | destroy() | |auto |
* | --------»----------------- \|/ |
* | DESTROYED |
* | |
* | stop() |
* ----»-----------------------------»------------------------------
*
* 任何一个状态都可以变为 FAILD
*/
public interface Lifecycle {
// 生命周期事件
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 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 {
}
}
生命周期监听器:
复制 public interface LifecycleListener {
// 接收事件对象,并处理事件
public void lifecycleEvent(LifecycleEvent event);
}
事件接口:
复制 import java.util.EventObject;
public final class LifecycleEvent extends EventObject {
private static final long serialVersionUID = 1L;
public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
super(lifecycle);
this.type = type;
this.data = data;
}
// 事件传递的数据
private final Object data;
// 事件的类型
private final String type;
public Object getData() {
return data;
}
// 事件所发生的目标生命周期
public Lifecycle getLifecycle() {
return (Lifecycle) getSource();
}
public String getType() {
return this.type;
}
}
组件的生命周期状态枚举:
复制 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);
// 组件是否可用
private final boolean available;
// 生命周期事件
private final String lifecycleEvent;
private LifecycleState(boolean available, String lifecycleEvent) {
this.available = available;
this.lifecycleEvent = lifecycleEvent;
}
public boolean isAvailable() {
return available;
}
public String getLifecycleEvent() {
return lifecycleEvent;
}
}