Servlet 体系原理与 Tomcat 执行流程
在 Java Web 开发体系中,Servlet 是处理 HTTP 请求的核心组件,而 Tomcat 作为主流的 Servlet 容器,承担着请求接收、解析、分发及响应返回的全流程管理。本文将从 Servlet 的核心体系原理入手,结合 Tomcat 的完整执行流程(含阻塞 / 非阻塞 I/O 模型),全方位拆解二者的协作逻辑与底层实现。
一、Servlet 核心体系:从接口规范到业务实现
Servlet 并非单一类,而是一套由「接口 - 抽象类 - 自定义实现」构成的分层体系,其设计核心是规范 Web 组件的生命周期,同时降低开发者的编码成本。

1. 根接口:javax.servlet.Servlet(规范定义)
Servlet接口是整个体系的基础,定义了 Servlet 的生命周期方法和核心服务能力,所有 Servlet 组件都必须遵循该规范:
java
public interface Servlet {
/**
* 初始化方法:Servlet对象创建后仅调用1次,用于初始化资源(如数据库连接)
*/
void init(ServletConfig config) throws ServletException;
/**
* 获取Servlet配置信息(如初始化参数、Servlet名称)
*/
ServletConfig getServletConfig();
/**
* 核心服务方法:每次请求触发1次,处理请求并生成响应
*/
void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
/**
* 获取Servlet元信息(如版本、作者)
*/
String getServletInfo();
/**
* 销毁方法:Servlet对象销毁前仅调用1次,用于释放资源(如关闭连接)
*/
void destroy();
}
2. 抽象实现:GenericServlet(简化开发)
GenericServlet是抽象类,实现了Servlet接口中除service()外的所有方法,核心作用是封装通用逻辑,减少重复编码:
java
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private transient ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init(); // 提供无参init(),供子类便捷重写
}
// 空实现的初始化方法,子类可按需重写
public void init() throws ServletException {}
@Override
public ServletConfig getServletConfig() {
return config;
}
// 抽象service()方法,强制子类实现核心业务逻辑
@Override
public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
@Override
public String getServletInfo() {
return ""; // 默认空实现,子类可自定义
}
@Override
public void destroy() {}
}
3. HTTP 适配:HttpServlet(Web 场景封装)
HttpServlet继承自GenericServlet,专门适配 HTTP 协议,将service()方法与 HTTP 请求方法(GET/POST/PUT 等)绑定,是 Web 开发中最常用的基类:
java
public abstract class HttpServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// 强转为HTTP专用请求/响应对象
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 根据HTTP请求方法分发到对应doXxx()方法
String method = request.getMethod();
if (method.equals(METHOD_GET)) {
doGet(request, response);
} else if (method.equals(METHOD_POST)) {
doPost(request, response);
} else if (method.equals(METHOD_PUT)) {
doPut(request, response);
} else if (method.equals(METHOD_DELETE)) {
doDelete(request, response);
}
// 其他HTTP方法(HEAD/OPTIONS等)同理
}
// 各HTTP方法的空实现,子类按需重写
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
throw new ServletException("GET method not supported");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
throw new ServletException("POST method not supported");
}
// 其他doXxx()方法省略...
}
4. 自定义 Servlet:业务落地
开发者只需继承HttpServlet,重写对应doXxx()方法即可实现业务逻辑,无需关注底层规范:
java
/**
* 自定义Servlet示例:处理/hello路径的GET请求
*/
@WebServlet("/hello") // 注解配置映射路径(替代web.xml)
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置响应编码和内容类型
resp.setContentType("text/html;charset=utf-8");
// 生成响应内容
resp.getWriter().write("<h1>Hello Servlet!</h1>");
}
}
二、Tomcat 完整执行流程(含 I/O 模型)
Tomcat 作为 Servlet 容器,核心职责是接收 HTTP 请求、匹配 Servlet、调用业务逻辑并返回响应。其执行流程的底层差异由 I/O 模型(BIO/NIO/AIO)决定,以下是完整流程拆解:
1. Tomcat 启动初始化
- 加载server.xml配置文件,初始化连接器(Connector)、引擎(Engine)、主机(Host)、上下文(Context);
- 解析web.xml或注解(如@WebServlet),建立「请求路径→Servlet 类」的映射关系,初始化 Servlet 容器(ServletContext);
- 根据配置启动对应 I/O 模型的监听端口(默认 8080)。
2. 核心执行流程(按阶段拆解)
阶段 1:监听端口,接收连接(I/O 模型核心差异点)
|--------------|-----------------------------------------------------------------------------------------------------------|
| I/O 模型 | 连接接收逻辑 |
| BIO(阻塞 I/O) | 启动 1 个监听线程,阻塞等待新连接;每接收 1 个连接,创建 1 个独立线程处理该请求(1 请求 = 1 线程)。 |
| NIO(非阻塞 I/O) | 启动 1 个 Selector(多路复用器)线程,监听所有 Socket 的「连接就绪」事件;接收连接后将 Socket 注册到 Selector,由 Selector 管理多个连接的事件(如读 / 写就绪)。 |
| AIO(异步 I/O) | 启动异步通道(AsynchronousServerSocketChannel),监听连接;接收连接后直接返回,由操作系统完成后续 I/O 操作,完成后回调应用程序方法。 |
阶段 2:解析 HTTP 请求
- 无论哪种 I/O 模型,Tomcat 都会通过InputStream读取请求数据,解析出请求行 (方法、路径、协议)、请求头 (Cookie/Host 等)、请求体(POST 参数);
- 将原生ServletRequest/ServletResponse封装为 HTTP 专用的HttpServletRequest/HttpServletResponse,补充请求路径、会话(Session)等 Web 相关属性。
阶段 3:匹配 Servlet 并管理生命周期
- 根据解析后的请求路径(如/hello),从 Servlet 容器的映射表中查找对应的 Servlet 类;
- 若 Servlet 未初始化:调用init()方法创建实例(仅首次请求执行,单例模式);
- 若 Servlet 已初始化:直接复用实例(Servlet 默认单例,需注意线程安全)。
阶段 4:调用 Servlet 处理请求
- 容器调用 Servlet 的service()方法,HttpServlet会根据 HTTP 方法分发到doGet()/doPost()等方法;
- 执行自定义业务逻辑(如数据库操作、数据处理),生成响应内容写入HttpServletResponse。
阶段 5:返回响应,连接收尾
|--------------|--------------------------------------------------------------------------------------------|
| I/O 模型 | 响应返回逻辑 |
| BIO(阻塞 I/O) | 处理线程通过 OutputStream 写入响应(阻塞直到数据写完),完成后销毁线程(或放回线程池),关闭连接。 |
| NIO(非阻塞 I/O) | 注册 Socket 的「写就绪」事件到 Selector;当 Selector 监听到事件,工作线程写入响应(非阻塞,数据未写完则暂存状态,后续事件再处理);完成后复用或关闭连接。 |
| AIO(异步 I/O) | 注册「写完成」回调函数,由操作系统完成响应写入;写入完成后触发回调,执行连接关闭 / 复用逻辑。 |
3. 完整流程图

4. 关键配置:切换 Tomcat I/O 模型
Tomcat 的 I/O 模型可通过server.xml的 Connector 配置修改,核心参数为protocol:
java
<!-- 1. BIO模式 -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Protocol"
connectionTimeout="20000"
redirectPort="8443"/>
<!-- 2. NIO模式(Tomcat8+默认) -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443"/>
<!-- 3. AIO模式 -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="20000"
redirectPort="8443"/>
三、核心总结
- Servlet 体系 :以Servlet接口为规范,GenericServlet简化通用实现,HttpServlet适配 HTTP 协议,最终通过自定义子类落地业务,核心是「生命周期管理 + 请求分发」;
- Tomcat 执行流程:核心是「连接接收→请求解析→Servlet 匹配→业务处理→响应返回」,底层 I/O 模型(BIO/NIO/AIO)决定了连接管理和数据读写的效率;
- 性能选型:低并发场景 BIO 足够,中高并发优先选 NIO(Tomcat 默认),超高性能需求可尝试 AIO(需操作系统支持)。
掌握 Servlet 体系原理和 Tomcat 执行流程,是理解 Java Web 底层运行机制的关键,也是优化 Web 应用性能的基础。