深入剖析Spring-Boot中Spring-MVC的请求处理流程
深入剖析Spring Boot中Spring MVC的请求处理流程
对于任何使用Spring Boot进行Web开发的开发者而言,深入理解Spring MVC的执行流程都是至关重要的。
这不仅有助于我们编写更清晰、更高效的代码,更是我们排查诡异问题、进行高级定制开发的知识基石。
今天,我们将一起深入Spring Boot应用的内核,揭开Spring MVC处理HTTP请求的神秘面纱。
一、核心设计:前端控制器模式
Spring MVC的核心架构基于前端控制器模式(Front Controller Pattern)。该模式的核心思想是:用一个中央控制器来统一接收所有请求,并将其分发给相应的处理组件 。
在Spring MVC中,这个中央控制器就是 DispatcherServlet。它是由Spring Boot通过自动配置(WebMvcAutoConfiguration)自动注册的,默认映射路径为 /,这意味着它成为了你应用处理所有Web请求的单一入口 和总调度中心 。
整个流程可以概括为:请求 -> DispatcherServlet -> 查找处理器 -> 执行处理器 -> 处理结果 -> 响应 。下面我们来分解这个过程的每一个细节。
二、详细执行流程“八步走”
假设用户发起了一个获取用户信息的请求:GET http://localhost:8080/api/users/1。
其处理流程如下图所示,你可以结合下文步骤来理解:

第1步:请求抵达 DispatcherServlet
所有HTTP请求首先都会被 DispatcherServlet 接收。它是整个流程的“大脑”,负责协调后续的所有工作。
第2步:HandlerMapping 寻找处理器
DispatcherServlet 本身不处理业务逻辑,它的首要任务是问询一个或多个 HandlerMapping 组件:“这个请求应该由谁来处理?”。
HandlerMapping 会根据请求的URL(如 /api/users/1),在注册的所有控制器中查找匹配的@RequestMapping方法。找到后,它会返回一个 HandlerExecutionChain 对象。这个对象不仅包含了目标处理器(即我们@Controller中的方法),还包含了配置好的拦截器****(HandlerInterceptor) 列表。
第3步:执行拦截器(Interceptor)的 preHandle
在真正执行业务逻辑之前,DispatcherServlet 会按顺序执行 HandlerExecutionChain 中所有拦截器的 preHandle 方法。
拦截器****在这里可以进行权限校验、日志记录、参数预处理等。如果某个拦截器认为请求不合法(如用户未登录),它的 preHandle 方法会返回 false,从而直接中断流程,跳转到最后一步。
第4步:HandlerAdapter 适配并执行处理器
不同的处理器可能有不同的执行方式(例如普通的@Controller和旧的Controller接口)。DispatcherServlet 需要找到一个能“驾驭”当前处理器的 HandlerAdapter。最常用的是 RequestMappingHandlerAdapter。
HandlerAdapter 是真正的“执行指挥官”,它负责:
- 数据绑定:将请求参数、URL路径变量、Session属性等绑定到处理器方法的参数上。我们常用的
@RequestParam、@PathVariable、@RequestBody等都是在这一步生效的。 - 数据验证:如果参数标注了
@Valid或@Validated,会在此触发校验框架。 - 调用方法:最终通过反射机制,调用我们的控制器方法(如
UserController.getUserById(id)),并获取其返回值。
第5步:处理器处理业务并返回
我们的控制器方法开始执行业务逻辑(如调用Service层查询用户数据),然后返回一个结果。这个结果通常有两种形式:
- 视图名(String):例如返回
"userInfo",表示需要渲染一个视图。 - 数据对象(Object):例如返回一个
User对象,这在@RestController中非常常见。
第6步:处理返回结果
这是流程的分水岭,DispatcherServlet 会根据返回结果的类型选择不同的处理策略:
- 返回视图名?交给
ViewResolver!
ViewResolver(视图解析器)会将逻辑视图名(如"userInfo")解析为一个具体的View对象(如对应/templates/userInfo.html的ThymeleafView)。后续View对象会负责将模型数据渲染到HTML模板中,生成最终页面。
- 返回对象?交给
HttpMessageConverter!
如果方法或类上有@ResponseBody注解(@RestController默认包含),DispatcherServlet会遍历配置的HttpMessageConverter(消息转换器)列表,选择一个合适的转换器(如MappingJackson2HttpMessageConverter),将返回的Java对象序列化为JSON、XML等格式,并直接写入HTTP响应体。
第7 & 8 步:拦截器收尾与响应返回
- 执行
postHandle:控制器方法执行后(但在视图渲染前 ),拦截器链会按逆序执行postHandle方法,允许对模型数据进行最后修改。 - 执行
afterCompletion:在整个请求处理完成(无论成功或异常)后,拦截器链会执行afterCompletion方法,用于进行资源清理工作(如关闭连接)。 - 最终,生成的响应(HTML页面或JSON数据)通过
DispatcherServlet返回给客户端浏览器。
三、不可或缺的异常处理机制
上述流程是“理想路径”。如果任何步骤抛出异常,流程会立即中断,并被 DispatcherServlet 捕获。
此时,DispatcherServlet 会转而委托 HandlerExceptionResolver 组件链来处理异常。这是我们实现统一异常处理的基础:
ExceptionHandlerExceptionResolver:支持我们使用@ControllerAdvice和@ExceptionHandler注解来全局处理异常。ResponseStatusExceptionResolver:处理标注了@ResponseStatus的异常。DefaultHandlerExceptionResolver:处理Spring内置的一些标准异常(如405 Method Not Allowed)。
异常解析器会将异常转换为一个友好的错误响应(如一个JSON错误信息),从而替代正常的流程结果。
总结
Spring MVC的流程清晰而模块化,每个组件各司其职:
DispatcherServlet是协调全局的大脑 。HandlerMapping是负责寻路的地图 。HandlerAdapter是真正干活的双手 。ViewResolver&HttpMessageConverter是包装成果的化妆师 。HandlerInterceptor是流程上的安检员 。HandlerExceptionResolver是兜底的消防员 。
Spring Boot的自动配置魔法让我们无需手动组装这些零件,但理解它们如何协同工作,无疑会让你从一个Spring Boot的使用者,蜕变成为一个真正的架构理解者。希望这篇剖析能帮助你更好地驾驭Spring Boot Web开发。