Tomcat Servlet 执行流程源码解析
Tomcat Servlet 执行流程源码解析
1. 引言
在前一篇中,我们剖析了 Tomcat 容器体系(Engine、Host、Context、Wrapper),知道了请求会逐层下沉,最终进入 Wrapper 容器 来执行具体的 Servlet。
那么:
- Servlet 是如何被加载和实例化的?
- 请求是如何经过 Filter、Listener 的?
- 最终是怎样进入 Servlet 的
service()
方法的?
本文将带你从源码角度,完整解析 Tomcat 的 Servlet 执行链路。
2. Servlet 生命周期
Servlet 生命周期由 Tomcat 的 Wrapper 容器(StandardWrapper) 管理:
-
加载(Load)
- 根据
web.xml
或@WebServlet
配置,Tomcat 会注册 Servlet 信息 - 若配置了
load-on-startup
,则在应用启动时就加载实例
- 根据
-
初始化(init)
- 调用
Servlet.init(ServletConfig config)
- 初始化资源(数据库连接池、缓存对象等)
- 调用
-
请求处理(service)
- 每次请求都会调用
service(HttpServletRequest req, HttpServletResponse res)
- 默认由
HttpServlet
分发到doGet
、doPost
等方法
- 每次请求都会调用
-
销毁(destroy)
- 在应用关闭时调用
destroy()
,释放资源
- 在应用关闭时调用
👉 生命周期图:
加载 → init() → service()...service() → destroy()
3. Filter 与 Listener
Servlet 执行链路中,还有两个重要机制:
(1) Filter 过滤器
- 定义在
web.xml
或@WebFilter
- 在请求进入 Servlet 之前 / 之后执行
- 类似 Spring 的 Interceptor
调用链:
Filter1 → Filter2 → ... → Servlet.service() → Filter2.after → Filter1.after
(2) Listener 监听器
- 定义在
web.xml
或@WebListener
- 监听应用、会话、请求的生命周期事件
- 如
ServletContextListener
,HttpSessionListener
4. Servlet 执行流程
当请求到达 Wrapper 容器 时,会进入其 Pipeline,最终由 StandardWrapperValve
调用 Servlet:
执行链路
Connector → Engine → Host → Context → Wrapper↓
Wrapper.Pipeline → StandardWrapperValve → FilterChain → Servlet.service()
5. 核心源码解析
(1) StandardWrapperValve 调用 Servlet
public class StandardWrapperValve extends ValveBase {@Overridepublic void invoke(Request request, Response response) {// 获取 Wrapper(Servlet 容器)StandardWrapper wrapper = (StandardWrapper) getContainer();// 创建或获取 Servlet 实例Servlet servlet = wrapper.allocate();// 构建过滤器链ApplicationFilterChain filterChain =ApplicationFilterFactory.createFilterChain(request, servlet);// 执行过滤器链(最终进入 Servlet.service)filterChain.doFilter(request, response);}
}
(2) ApplicationFilterChain(责任链模式)
public final class ApplicationFilterChain implements FilterChain {private int pos = 0; // 当前执行到哪个 Filterprivate Filter[] filters;private Servlet servlet;@Overridepublic void doFilter(ServletRequest request, ServletResponse response)throws IOException, ServletException {if (pos < filters.length) {Filter filter = filters[pos++];filter.doFilter(request, response, this);} else {// 过滤器执行完毕,进入 Servletservlet.service(request, response);}}
}
👉 可以看到,Tomcat 使用 FilterChain 递归调用 来执行多个过滤器,最后才进入 Servlet。
(3) HttpServlet 执行
public abstract class HttpServlet extends GenericServlet {@Overridepublic void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) res;String method = request.getMethod();if (method.equals("GET")) {doGet(request, response);} else if (method.equals("POST")) {doPost(request, response);} else {// 其他 HTTP 方法doOther(request, response);}}
}
6. 请求执行链总结
完整的请求执行流程如下:
1. Connector 接收请求
2. Engine → Host → Context → Wrapper 定位目标 Servlet
3. StandardWrapperValve 分配 Servlet 实例
4. 构建 ApplicationFilterChain
5. 依次执行 Filter.doFilter()
6. 执行 Servlet.service() → doGet()/doPost()
7. 返回响应,按 Filter 逆序退出
7. 配置示例
web.xml 配置
<filter><filter-name>AuthFilter</filter-name><filter-class>com.demo.AuthFilter</filter-class>
</filter>
<filter-mapping><filter-name>AuthFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>com.demo.HelloServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern>
</servlet-mapping>
8. 总结
本篇文章我们完整剖析了 Servlet 的执行流程:
- 生命周期:init → service → destroy
- Filter 链:责任链模式,拦截请求
- Listener:监听应用 / 会话 / 请求事件
- 核心源码:StandardWrapperValve、ApplicationFilterChain、HttpServlet
这样,我们就完整理解了 Tomcat 如何从请求路由到 Servlet 执行 的整个链路。