spring boot 请求分发器
请求分发器(Request Dispatcher)的核心机制是由 DispatcherServlet 实现的。它是整个 Spring Web MVC 框架的前端控制器(Front Controller),负责接收所有 HTTP 请求,并将其分发(dispatch)给合适的处理器(Handler,通常是 @Controller 中的方法)。
一、什么是 DispatcherServlet?
DispatcherServlet 是 Spring MVC 的核心类,继承自 HttpServlet,实现了请求的统一入口和分发逻辑。
- 在 Spring Boot 中,无需手动配置
web.xml,DispatcherServlet会自动注册(默认路径为/)。 - 所有进入应用的 HTTP 请求(除静态资源等被排除的)都会经过它。
二、请求分发的完整流程(9 步)
当一个 HTTP 请求到达 Spring Boot 应用时,DispatcherServlet 按以下顺序处理:
1. 接收请求
- 容器(如 Tomcat)将请求交给
DispatcherServlet.service()方法。
2. 调用 doDispatch()
- 核心分发方法,协调后续所有组件。
3. 查找 Handler(处理器)
- 使用
HandlerMapping接口的实现类(如RequestMappingHandlerMapping)。 - 根据 URL、HTTP 方法等匹配到对应的
@Controller中的@RequestMapping方法。 - 返回一个
HandlerExecutionChain(包含目标方法 + 拦截器)。
// 示例:/api/user → UserController.getUser()4. 查找 HandlerAdapter(处理器适配器)
- 使用
HandlerAdapter(如RequestMappingHandlerAdapter)。 - 负责调用目标方法(支持参数解析、数据绑定、验证等)。
5. 执行拦截器的 preHandle()
- 如果配置了
HandlerInterceptor,会先执行preHandle()。 - 返回
false则中断流程。
6. 调用目标 Controller 方法
HandlerAdapter反射调用你的@GetMapping/@PostMapping方法。- 自动完成:
- 参数解析(
@PathVariable,@RequestBody,@RequestParam等) - 数据绑定(表单 → Java 对象)
- 验证(
@Valid) - 返回值处理
- 参数解析(
7. 处理返回值(ModelAndView / ResponseEntity / String 等)
- 由
HandlerMethodReturnValueHandler处理返回值。 - 决定是渲染视图(Thymeleaf)还是写入响应体(JSON)。
8. 执行拦截器的 postHandle()
- 在视图渲染前执行(对
@ResponseBody无效,因为无视图)。
9. 渲染视图 或 写入响应体
- 如果返回的是视图名(如
"home"):- 使用
ViewResolver(如ThymeleafViewResolver)解析模板。 - 渲染 HTML 并写入
HttpServletResponse。
- 使用
- 如果是
@RestController或@ResponseBody:- 使用
HttpMessageConverter(如Jackson2ObjectMapper)将对象转为 JSON。 - 直接写入响应体(
response.getWriter().write(json))。
- 使用
10. 执行拦截器的 afterCompletion()
- 无论成功或异常,最终都会执行(类似 finally)。
⚠️ 注意:对于
@ResponseBody或ResponseEntity,没有视图渲染阶段,直接写入响应。
三、关键组件一览
| 组件 | 作用 | 常见实现 |
|---|---|---|
DispatcherServlet | 前端控制器,总调度 | Spring 内置 |
HandlerMapping | 根据 URL 找到处理器 | RequestMappingHandlerMapping |
HandlerAdapter | 调用处理器方法 | RequestMappingHandlerAdapter |
HandlerInterceptor | 拦截请求(类似 AOP) | 自定义实现 |
ViewResolver | 解析视图名 → View 对象 | ThymeleafViewResolver |
HttpMessageConverter | 对象 ↔ JSON/XML 等 | MappingJackson2HttpMessageConverter |
四、Spring Boot 中的自动配置
Spring Boot 通过 WebMvcAutoConfiguration 自动配置了上述所有组件:
- 自动注册
DispatcherServlet(路径/) - 自动启用
@EnableWebMvc的大部分功能(但不完全等同) - 自动配置 JSON 转换器(Jackson)、静态资源处理、拦截器支持等
你也可以通过以下方式自定义:
1. 添加拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/api/**");}
}2. 自定义消息转换器
@Bean
public HttpMessageConverters customConverters() {// 添加自定义 converter
}3. 修改 DispatcherServlet 路径(不推荐)
# application.properties
server.servlet.context-path=/app
spring.mvc.servlet.path=/mvc/*五、请求分发示意图
HTTP Request↓
[DispatcherServlet]↓
[HandlerMapping] → 找到 @Controller 方法↓
[HandlerAdapter] → 调用方法(参数解析、验证等)↓
[ReturnValueHandler] → 处理返回值↓├── 若为视图名 → [ViewResolver] → 渲染 HTML└── 若为 @ResponseBody → [HttpMessageConverter] → 写 JSON 到响应↓
HTTP Response六、常见问题
Q1:为什么我的 Controller 方法没被调用?
- 检查
@Controller/@RestController是否标注 - 检查
@RequestMapping路径是否匹配 - 检查是否被
@ComponentScan扫描到
Q2:如何调试请求分发过程?
- 开启日志:
logging.level.org.springframework.web=DEBUG - 查看
DispatcherServlet的 debug 输出
Q3:静态资源(如 /js/app.js)会被分发吗?
- 不会。Spring Boot 默认通过
ResourceHttpRequestHandler处理/static,/public,/resources等路径,绕过 Controller。
简单理解
初学者记住这 3 句话:
- 所有请求先到
DispatcherServlet(迎宾员),它是总指挥。 - 它根据 URL 找到对应的
@Controller方法(厨师)来处理。 - 处理完的结果,自动变成 JSON 或网页返回给你,你不用操心怎么“送回去”。
举个代码例子
@RestController
public class OrderController {@GetMapping("/order/chicken")public String orderChicken() {return "宫保鸡丁已下单!"; // 自动变成 JSON 字符串返回}
}当你在浏览器访问:http://localhost:8080/order/chicken
→ 就像在餐厅点菜,Spring Boot 自动完成所有分发流程,返回文字给你。
