Tomcat Servlet 执行流程源码解析

在这里插入图片描述

1. 引言

在前一篇中,我们剖析了 Tomcat 容器体系(Engine、Host、Context、Wrapper),知道了请求会逐层下沉,最终进入 Wrapper 容器 来执行具体的 Servlet
那么:

  • Servlet 是如何被加载和实例化的?
  • 请求是如何经过 Filter、Listener 的?
  • 最终是怎样进入 Servlet 的 service() 方法的?

本文将带你从源码角度,完整解析 Tomcat 的 Servlet 执行链路


2. Servlet 生命周期

Servlet 生命周期由 Tomcat 的 Wrapper 容器(StandardWrapper) 管理:

  1. 加载(Load)

    • 根据 web.xml@WebServlet 配置,Tomcat 会注册 Servlet 信息
    • 若配置了 load-on-startup,则在应用启动时就加载实例
  2. 初始化(init)

    • 调用 Servlet.init(ServletConfig config)
    • 初始化资源(数据库连接池、缓存对象等)
  3. 请求处理(service)

    • 每次请求都会调用 service(HttpServletRequest req, HttpServletResponse res)
    • 默认由 HttpServlet 分发到 doGetdoPost 等方法
  4. 销毁(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 {
    @Override
    public 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; // 当前执行到哪个 Filter
    private Filter[] filters;
    private Servlet servlet;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response)
        throws IOException, ServletException {
        if (pos < filters.length) {
            Filter filter = filters[pos++];
            filter.doFilter(request, response, this);
        } else {
            // 过滤器执行完毕,进入 Servlet
            servlet.service(request, response);
        }
    }
}

👉 可以看到,Tomcat 使用 FilterChain 递归调用 来执行多个过滤器,最后才进入 Servlet。


(3) HttpServlet 执行

public abstract class HttpServlet extends GenericServlet {
    @Override
    public 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 执行 的整个链路。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐