Tomcat 容器(Container)体系源码剖析
四层结构请求流转:逐层匹配,最终定位 ServletPipeline-Valve 机制:责任链模式,支持扩展核心源码容器是Tomcat 的请求调度核心,理解它的分层和 Pipeline 机制,才能真正掌握请求是如何一步步路由到 Servlet 的。
·
Tomcat 容器(Container)体系源码剖析
1. 引言
在上一章中,我们剖析了 Connector(连接器),它负责接收网络请求并解析协议。
但真正决定请求如何被分发、哪个 Servlet 来处理的,是 Tomcat 的 容器(Container)。
Tomcat 使用 分层容器模型,并结合 Pipeline-Valve 责任链模式,实现了灵活的请求处理机制。
2. 容器体系结构
Tomcat 的 Container 体系分为四层:
-
Engine
- 一个 Service 下只能有一个 Engine
- 代表整个 Servlet 引擎
- 管理多个虚拟主机(Host)
-
Host
- 代表一个虚拟主机(域名绑定)
- 一个 Engine 下可以有多个 Host
-
Context
- 代表一个 Web 应用(
webapps/
下的项目) - 负责加载
web.xml
配置
- 代表一个 Web 应用(
-
Wrapper
- 代表单个 Servlet
- 负责 Servlet 的生命周期管理(init、service、destroy)
👉 结构图:
Engine
└── Host
└── Context
└── Wrapper (Servlet)
3. 请求流转机制
请求从 Connector 进入后,会进入 Container 层级:
Connector → Engine → Host → Context → Wrapper → Servlet
例子:访问 http://localhost:8080/demo/hello
- Engine:定位默认 Engine
- Host:根据
localhost
定位 Host - Context:根据
/demo
定位应用 - Wrapper:根据
/hello
映射到某个 Servlet
4. Pipeline-Valve 机制
Tomcat 使用 责任链模式 来实现请求处理。
- Pipeline:管道,维护多个 Valve(阀门)
- Valve:具体的处理节点,可以插入过滤逻辑
- StandardPipeline:默认实现
- StandardValve:容器的核心处理逻辑
执行流程:
Pipeline → Valve1 → Valve2 → ... → StandardValve → 下级容器
这样设计的好处:
- 方便扩展(例如 AccessLogValve、ErrorReportValve)
- 支持灵活的拦截处理(类似 Spring 的拦截器链)
5. 核心源码解析
(1) Container 接口
Tomcat 的四个容器(Engine、Host、Context、Wrapper)都实现了 org.apache.catalina.Container
接口:
public interface Container extends Lifecycle {
String getName();
Pipeline getPipeline();
void addChild(Container child);
Container findChild(String name);
}
addChild
:添加子容器findChild
:根据名称查找子容器getPipeline
:获取当前容器的 Pipeline
(2) Engine 实现
public class StandardEngine extends ContainerBase implements Engine {
@Override
public void startInternal() {
// 启动所有子 Host 容器
for (Container child : findChildren()) {
child.start();
}
}
}
(3) Host 实现
public class StandardHost extends ContainerBase implements Host {
@Override
protected void startInternal() {
// 加载 Context(Web 应用)
deployApps();
}
}
(4) Context 实现
public class StandardContext extends ContainerBase implements Context {
@Override
protected void startInternal() {
// 解析 web.xml,加载 Servlet、Filter、Listener
loadOnStartup(findChildren());
}
}
(5) Wrapper 实现
public class StandardWrapper extends ContainerBase implements Wrapper {
@Override
public Servlet loadServlet() {
// 通过反射创建 Servlet 实例
return (Servlet) instanceManager.newInstance(servletClass);
}
}
(6) Pipeline 与 Valve
Pipeline 的默认实现:
public class StandardPipeline implements Pipeline {
protected Valve basic;
protected List<Valve> valves = new ArrayList<>();
@Override
public void addValve(Valve valve) {
valves.add(valve);
}
@Override
public Valve getBasic() {
return basic; // 最终调用 StandardValve
}
}
6. 请求处理流程源码追踪
以 Context 为例:
public class StandardContextValve extends ValveBase {
@Override
public void invoke(Request request, Response response) {
// 定位目标 Wrapper(Servlet)
Wrapper wrapper = request.getWrapper();
wrapper.getPipeline().getFirst().invoke(request, response);
}
}
最终进入 Wrapper → Servlet.service():
public class StandardWrapperValve extends ValveBase {
@Override
public void invoke(Request request, Response response) {
// 调用 Servlet 的 service 方法
servlet.service(request, response);
}
}
7. 配置与应用
在 server.xml
中定义容器:
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps">
<Context path="/demo" docBase="demo"/>
</Host>
</Engine>
8. 总结
在本篇中,我们深入剖析了 Tomcat 容器体系:
- 四层结构:Engine → Host → Context → Wrapper
- 请求流转:逐层匹配,最终定位 Servlet
- Pipeline-Valve 机制:责任链模式,支持扩展
- 核心源码:StandardEngine、StandardHost、StandardContext、StandardWrapper
容器是 Tomcat 的请求调度核心,理解它的分层和 Pipeline 机制,才能真正掌握请求是如何一步步路由到 Servlet 的。
更多推荐
所有评论(0)