Spring MVC 九大核心角色详解:请求处理链路中的每一个关键组件
一、九大核心角色速览
Spring MVC 的请求处理流程由一组职责明确的组件协作完成。这九大角色是:
| 序号 | 角色 | 核心职责 |
|---|---|---|
| 1 | DispatcherServlet |
前端控制器,全局调度中心 |
| 2 | HandlerMapping |
根据请求找到对应的 Handler |
| 3 | HandlerAdapter |
调用 Handler,完成参数绑定和返回值处理 |
| 4 | Handler(Controller) |
开发者编写的业务处理方法 |
| 5 | HandlerInterceptor |
拦截器,在 Handler 前后插入逻辑 |
| 6 | HandlerExceptionResolver |
异常解析器,统一处理执行过程中的异常 |
| 7 | ViewResolver |
视图解析器,把逻辑视图名解析成 View |
| 8 | View |
视图,负责渲染页面或输出内容 |
| 9 | HttpMessageConverter |
消息转换器,负责请求体/响应体与 Java 对象的转换 |
这九个角色按请求执行的顺序协作,每个角色只负责一件事。
二、逐角色详解
1. DispatcherServlet:前端控制器
职责:接收所有请求,调度其他八个角色完成处理。
核心作用:
- 是整个流程的唯一入口。
- 不执行业务逻辑,只负责"把请求交给谁、按什么顺序执行"。
- 持有
HandlerMapping、HandlerAdapter、ViewResolver、HandlerExceptionResolver等组件的引用。
配置方式:
xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
关键源码 :DispatcherServlet.doDispatch() 是整个请求处理的核心方法。
2. HandlerMapping:处理器映射器
职责:根据请求的 URL 和方法,找到对应的 Handler。
核心作用:
- 维护"路径 + 请求方法 → Handler"的映射表。
- 返回
HandlerExecutionChain,包含 Handler 和匹配的拦截器列表。 - 找不到 Handler 时,返回 404。
常见实现:
| 实现类 | 作用 |
|---|---|
RequestMappingHandlerMapping |
解析 @RequestMapping、@GetMapping 等注解 |
BeanNameUrlHandlerMapping |
按 Bean 名称匹配 URL |
SimpleUrlHandlerMapping |
按配置的 URL 映射匹配 |
RouterFunctionMapping |
函数式路由 |
实际使用 :日常开发中几乎只用 RequestMappingHandlerMapping,由 <mvc:annotation-driven/> 自动注册。
3. HandlerAdapter:处理器适配器
职责:调用 Handler,完成参数绑定和返回值处理。
核心作用:
DispatcherServlet不直接调用 Controller,而是交给HandlerAdapter。- 适配不同类型的 Handler(注解方法、接口实现、函数式端点)。
- 负责参数解析、反射调用、返回值处理。
常见实现:
| 实现类 | 适配的 Handler 类型 |
|---|---|
RequestMappingHandlerAdapter |
@RequestMapping 标注的方法 |
HttpRequestHandlerAdapter |
HttpRequestHandler 接口实现 |
SimpleControllerHandlerAdapter |
Controller 接口实现 |
关键源码 :RequestMappingHandlerAdapter.invokeHandlerMethod() 负责调用 Controller 方法。
4. Handler(Controller):处理器
职责:开发者编写的业务处理方法。
核心作用:
- 接收请求参数。
- 调用 Service 完成业务逻辑。
- 返回结果(视图名、对象、
ModelAndView、ResponseEntity等)。
示例:
java
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
}
注意 :Handler 不一定是 @Controller 标注的类。任何能被 HandlerAdapter 调用的对象都可以是 Handler。
5. HandlerInterceptor:拦截器
职责:在 Handler 执行前后插入自定义逻辑。
核心作用:
preHandle:Controller 之前执行,返回false中断流程。postHandle:Controller 之后、视图渲染之前执行。afterCompletion:视图渲染之后执行,适合清理资源。
典型用途:
- 登录校验。
- 权限校验。
- 链路追踪。
- 请求耗时统计。
注册方式:
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/login", "/static/**");
}
}
易错点 :preHandle 返回 false 时,当前拦截器的 postHandle 和 afterCompletion 不执行,但之前已放行的拦截器的 afterCompletion 仍会执行。
6. HandlerExceptionResolver:异常解析器
职责:处理 Handler 执行过程中抛出的异常。
核心作用:
- 把异常转换成统一的 HTTP 响应。
- 按顺序遍历解析器,找到第一个能处理的就停止。
Spring MVC 内置三个解析器:
| 解析器 | 处理对象 |
|---|---|
ExceptionHandlerExceptionResolver |
@ExceptionHandler 标注的方法 |
ResponseStatusExceptionResolver |
@ResponseStatus 标注的异常类或方法 |
DefaultHandlerExceptionResolver |
Spring MVC 内置标准异常 |
实际使用 :日常开发用 @RestControllerAdvice + @ExceptionHandler,底层由 ExceptionHandlerExceptionResolver 执行。
java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<String> handleBusiness(BusinessException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
注意 :HandlerExceptionResolver 只处理 DispatcherServlet 内部的异常。Filter 中抛出的异常、视图渲染阶段的异常不归它管。
7. ViewResolver:视图解析器
职责 :把逻辑视图名解析成具体的 View 对象。
核心作用:
- Controller 返回
"user",ViewResolver把它解析成/WEB-INF/templates/user.html对应的View。 - 支持前缀后缀拼接、内容协商、多视图技术共存。
常见实现:
| 实现类 | 视图技术 |
|---|---|
ThymeleafViewResolver |
Thymeleaf |
InternalResourceViewResolver |
JSP |
FreeMarkerViewResolver |
FreeMarker |
ContentNegotiatingViewResolver |
根据 Accept 头选择视图 |
配置示例:
xml
<bean id="viewResolver"
class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
注意 :@ResponseBody 时不经过 ViewResolver。
8. View:视图
职责:把模型数据渲染成最终的 HTTP 响应。
核心作用:
- 接收
Model和HttpServletRequest。 - 生成 HTML、JSON、PDF 等内容。
- 写入
HttpServletResponse。
常见实现:
| 实现类 | 输出内容 |
|---|---|
ThymeleafView |
Thymeleaf 模板渲染的 HTML |
InternalResourceView |
JSP 渲染的 HTML |
RedirectView |
302 重定向 |
MappingJackson2JsonView |
JSON |
关键方法:
java
void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception;
执行时机 :ViewResolver 解析出 View 之后,DispatcherServlet 调用 View.render()。
9. HttpMessageConverter:消息转换器
职责:负责 HTTP 请求/响应体与 Java 对象之间的相互转换。
核心作用:
@RequestBody时,把请求体反序列化成 Java 对象。@ResponseBody时,把 Java 对象序列化成响应体。- 根据
Content-Type和Accept头选择匹配的转换器。
常见实现:
| 实现类 | 处理类型 |
|---|---|
MappingJackson2HttpMessageConverter |
JSON 与对象互转 |
StringHttpMessageConverter |
String 与文本互转 |
ByteArrayHttpMessageConverter |
byte\[\] 与二进制互转 |
ResourceHttpMessageConverter |
Resource 与文件流互转 |
FormHttpMessageConverter |
MultiValueMap 与表单互转 |
触发场景:
@RequestBody。@ResponseBody。@RestController的所有方法。RequestEntity、ResponseEntity。
易错点:
StringHttpMessageConverter优先级高于 Jackson,返回String时输出纯文本,不加双引号。Content-Type不匹配时返回 415,Accept不匹配时返回 406。
三、九大角色的协作关系
1. 执行顺序
请求
→ DispatcherServlet
→ HandlerMapping
→ HandlerInterceptor.preHandle
→ HandlerAdapter
→ Handler
→ HttpMessageConverter(读请求体、写响应体)
→ ViewResolver(需要渲染视图时)
→ View.render
→ HandlerInterceptor.postHandle
→ HandlerInterceptor.afterCompletion
→ 响应
2. 异常处理链路
Handler 抛出异常
→ HandlerExceptionResolver
→ @ExceptionHandler 方法
→ 生成响应
3. 依赖关系
| 角色 | 依赖的角色 |
|---|---|
DispatcherServlet |
持有 HandlerMapping、HandlerAdapter、ViewResolver、HandlerExceptionResolver |
HandlerMapping |
返回 HandlerExecutionChain(包含 Handler 和 HandlerInterceptor) |
HandlerAdapter |
依赖 Handler,返回值处理依赖 HttpMessageConverter 或 ViewResolver |
ViewResolver |
返回 View |
View |
依赖 HttpMessageConverter 或模板引擎 |
HttpMessageConverter |
独立工作,由 HandlerAdapter 或 View 调用 |
4. 用图表示
DispatcherServlet
├── HandlerMapping → HandlerExecutionChain
│ ├── Handler
│ └── HandlerInterceptor 列表
├── HandlerAdapter → Handler
│ ├── HttpMessageConverter
│ └── ViewResolver → View
├── HandlerExceptionResolver
└── ViewResolver → View → HttpMessageConverter
四、九个角色与三大核心流程的对应
Spring MVC 有三大核心流程,每个流程由不同角色协作完成。
| 流程 | 参与角色 |
|---|---|
| 路由流程 | DispatcherServlet、HandlerMapping |
| 执行流程 | HandlerAdapter、Handler、HandlerInterceptor、HttpMessageConverter |
| 响应流程 | ViewResolver、View、HttpMessageConverter、HandlerExceptionResolver |
1. 路由流程
DispatcherServlet 接收请求,HandlerMapping 找到 Handler 和拦截器。
2. 执行流程
HandlerAdapter 调用 Handler,HandlerInterceptor 在前后插入逻辑,HttpMessageConverter 负责参数和返回值的序列化。
3. 响应流程
如果返回视图名,ViewResolver 解析 View,View 渲染响应。如果返回对象且带 @ResponseBody,HttpMessageConverter 直接写响应体。如果抛出异常,HandlerExceptionResolver 兜底。
五、和面试常见问题的对应
| 面试问题 | 对应角色 |
|---|---|
| Spring MVC 为什么需要 HandlerMapping 和 HandlerAdapter 两个组件 | HandlerMapping、HandlerAdapter |
| 拦截器和过滤器有什么区别 | HandlerInterceptor |
@ResponseBody 是怎么把对象变成 JSON 的 |
HttpMessageConverter |
| 视图解析器是怎么找到模板的 | ViewResolver、View |
| 全局异常处理器怎么生效的 | HandlerExceptionResolver |
| 为什么请求会 404、415、406 | 分别对应 HandlerMapping、HttpMessageConverter(读)、HttpMessageConverter(写) |
六、记忆方法
1. 一句话口诀
一调度,二映射,三适配,四处理,
五拦截,六异常,七解析,八渲染,九转换。
对应:
DispatcherServlet → HandlerMapping → HandlerAdapter → Handler
→ HandlerInterceptor → HandlerExceptionResolver
→ ViewResolver → View → HttpMessageConverter
2. 按职责分类记
| 类别 | 角色 |
|---|---|
| 调度类 | DispatcherServlet |
| 查找类 | HandlerMapping |
| 执行类 | HandlerAdapter、Handler |
| 增强类 | HandlerInterceptor、HandlerExceptionResolver |
| 响应类 | ViewResolver、View、HttpMessageConverter |
口诀:
调度查找执行,增强响应,九人一条链。
3. 按请求阶段记
进来先找:HandlerMapping
执行前后:Interceptor
调用方法:HandlerAdapter + Handler
出错兜底:HandlerExceptionResolver
需要页面:ViewResolver + View
读写数据:HttpMessageConverter
4. 和 Spring MVC 核心链路口诀对应
接请求 → DispatcherServlet
找方法 → HandlerMapping
调方法 → HandlerAdapter + Handler
解视图 → ViewResolver
渲响应 → View
转数据 → HttpMessageConverter
拦前后 → HandlerInterceptor
兜异常 → HandlerExceptionResolver
5. 排查口诀
404 → HandlerMapping
415 → HttpMessageConverter 读
406 → HttpMessageConverter 写
500 → HandlerExceptionResolver 是否捕获
页面找不到 → ViewResolver
拦截器没执行 → HandlerInterceptor 注册路径
七、总结
| 序号 | 角色 | 一句话职责 |
|---|---|---|
| 1 | DispatcherServlet |
总调度中心,接请求、协调其他角色 |
| 2 | HandlerMapping |
根据路径找 Handler 和拦截器 |
| 3 | HandlerAdapter |
调用 Handler,处理参数和返回值 |
| 4 | Handler |
开发者编写的业务方法 |
| 5 | HandlerInterceptor |
在 Handler 前后插入逻辑 |
| 6 | HandlerExceptionResolver |
统一处理执行过程中的异常 |
| 7 | ViewResolver |
把视图名解析成 View |
| 8 | View |
渲染页面或输出内容 |
| 9 | HttpMessageConverter |
请求体/响应体与 Java 对象互转 |
这九个角色可以分成四组:调度(DispatcherServlet)、查找(HandlerMapping)、执行(HandlerAdapter + Handler)、增强(Interceptor + ExceptionResolver)、响应(ViewResolver + View + HttpMessageConverter) 。记住"一调度、二映射、三适配、四处理、五拦截、六异常、七解析、八渲染、九转换",再把每个角色和它在流程中的位置对应起来,Spring MVC 的组件体系就能理清。九个角色不是并列关系,而是围绕 DispatcherServlet 按请求生命周期依次登场,各司其职。