Spring Web网络请求执行流程

最近在梳理我的项目,回首发现很多基础的处理流程由框架接手,我甚至对自己的代码感到一些陌生,无法详细、基础的梳理数据的输入、处理、输出流程,于是我开始详细地复习和总结一些基础的知识,并尽量将其整理和流畅的描述

本文中我将梳理对Spring Web的理解,尽量详细、简洁、准确地描述其完整的处理流程。

将包括从 Tomcat 作为 Web 服务器接收请求,到 Spring MVC 中的控制器路由映射,再到 DispatcherServlet 的具体工作流程。

在 Spring Web(包括 Spring MVC 和 Spring Boot)中,控制器(Controller)层的路由映射是通过注解驱动的方式实现的。Spring MVC 会扫描带有特定注解的类和方法,自动将请求的 URL 映射到相应的控制器方法。

控制器路由映射实现原理

  1. Tomcat 的角色
    • 在 Spring Web 应用中,Tomcat 作为 Servlet 容器,负责接收 HTTP 请求并将请求传递给相应的 DispatcherServlet。Tomcat 是整个请求处理流程的起点,但并不直接参与 Spring MVC 的路由映射。
    • 它通过配置的 Connector 组件监听指定端口(例如 8080),接收到客户端请求后,将其交给适当的 Servlet 进行处理。在 Spring Boot 或 Spring MVC 应用中,这通常是 DispatcherServlet
  2. 控制器类注解
    • 控制器类通常会使用 @Controller@RestController 注解标记。这些注解告诉 Spring MVC 这个类是一个控制器,并且应该被扫描。
  3. 请求映射注解
    • 控制器方法通常会使用 @RequestMapping 或它的派生注解,如 @GetMapping, @PostMapping, @PutMapping, @DeleteMapping 等来指定 HTTP 请求的方法和路径。这些注解定义了方法与 URL 的映射关系。
  4. 扫描控制器类
    • Spring MVC 通过 @ComponentScan 或者 @SpringBootApplication 注解来扫描控制器类。扫描过程中,Spring MVC 会找到所有标记为控制器的类,并将它们注册为 Spring Bean。
  5. 请求分发
    • 当一个 HTTP 请求到达时,Tomcat 会将请求转发给 Spring MVC 的 DispatcherServletDispatcherServlet 负责接收请求并进行进一步的处理。具体来说,它会根据请求 URL 和 HTTP 方法(GET、POST 等)选择合适的控制器方法进行调用。
  6. 请求映射解析
    • Spring MVC 使用 HandlerMapping 接口的实现类来解析请求 URL 并将其映射到控制器方法上。默认情况下,Spring MVC 使用 RequestMappingHandlerMapping 来处理 @RequestMapping 注解。
    • HandlerMapping 会查找与请求匹配的控制器方法,并将请求传递给该方法。
  7. 参数绑定
    • Spring MVC 可以自动将请求参数绑定到控制器方法的参数上,通过使用 @RequestParam, @PathVariable, @RequestBody, @ModelAttribute 等注解。通过这些注解,Spring MVC 会自动从请求中提取数据并将其绑定到控制器方法的参数上。
  8. 视图渲染
    • 控制器方法返回一个视图名称或模型视图对象。 DispatcherServlet 会将视图名称交给视图解析器来查找实际的视图,并渲染视图。

DispatcherServlet 解析

DispatcherServlet 是 Spring MVC 中的核心组件,负责处理所有的 HTTP 请求,并将请求分发到合适的控制器方法。它管理着整个请求-响应周期,确保请求的处理和响应的生成。

DispatcherServlet 作用

  1. 请求入口
    • 客户端发起的所有请求首先由 DispatcherServlet 接收,并转发给适当的处理器(控制器方法)。
  2. 请求分发
    • DispatcherServlet 使用 HandlerMappingHandlerAdapter 来选择合适的控制器方法,并绑定请求参数。
  3. 视图渲染
    • 执行完控制器方法后,DispatcherServlet 选择并渲染视图,通过 ViewResolver 解析视图名。
  4. 拦截器支持
    • DispatcherServlet 支持拦截器,可以在请求处理前后执行操作,如日志记录、权限验证等。
  5. 异常处理
    • DispatcherServlet 处理控制器抛出的异常,并转换为适当的错误视图或错误响应。

DispatcherServlet 工作流程

  1. 请求到达
    • Web 服务器(如 Tomcat)接收 HTTP 请求并将其转发给 DispatcherServlet
  2. 获取请求信息
    • DispatcherServletHttpServletRequest 获取请求方法、URL、参数等信息。
  3. 请求映射
    • DispatcherServlet 通过 HandlerMapping 解析请求 URL,找到匹配的控制器方法。
  4. 创建 HandlerExecutionChain
    • 通过 HandlerMapping,找到控制器方法并创建 HandlerExecutionChain,它包含控制器方法和相关拦截器。
  5. 调用控制器方法
    • 使用 HandlerAdapter 调用控制器方法,并将请求参数绑定到方法的参数上。
  6. 视图渲染
    • 控制器返回视图或模型视图对象,DispatcherServlet 使用 ViewResolver 渲染视图。
  7. 响应生成
    • 最终,生成的响应通过 HttpServletResponse 发送回客户端。

Tomcat 如何处理 HTTP 请求

Tomcat 作为 Web 服务器,处理 HTTP 请求的流程涉及多个步骤,主要通过 ConnectorHostContext 组件来完成。

Tomcat 接收 HTTP 请求的流程

  1. 网络层
    • 客户端发起 HTTP 请求,通过网络传输到服务器。
  2. Connector 组件
    • Tomcat 的 Connector 组件负责监听指定端口并接收客户端的 HTTP 请求。它支持多种协议(如 HTTP/1.1、HTTPS、AJP)。
  3. Host 和 Context
    • Connector 接收到请求后,基于请求的主机名(Host header)和上下文路径(Context path),将请求分发给相应的 HostContext 组件。
  4. Web 应用容器
    • 请求分发给正确的 Context 后,Tomcat 的 Web 应用容器(Servlet 容器)处理请求。
  5. Servlet 容器
    • Servlet 容器通过 URL 映射找到合适的 Servlet,并调用其 service() 方法来处理请求。
  6. DispatcherServlet(Spring MVC)
    • 在 Spring MVC 应用中,DispatcherServlet 负责接收请求并将其分发到控制器方法。
  7. 视图渲染和响应生成
    • 控制器方法执行后,DispatcherServlet 通过视图解析器渲染视图,最终将响应发送回客户端。

Tomcat Connector 组件

  1. 配置 Connector
    • server.xml 文件中配置 Connector,指定监听端口、协议类型等。
  2. 监听网络连接
    • Connector 监听指定端口,接收客户端连接并解析 HTTP 请求。
  3. 请求处理
    • Connector 会从线程池中分配线程,读取并解析 HTTP 请求,传递给后续组件处理。
  4. 响应发送
    • 一旦请求处理完毕,Connector 会将响应写回客户端,并管理连接状态。