Spring MVC请求处理流程

Spring MVC请求处理流程

Spring MVC 是基于 Servlet 的 Web 框架。理解请求处理流程,有助于自定义扩展和排查问题。

核心组件

组件 作用
DispatcherServlet 前端控制器,统一接收请求
HandlerMapping 请求 -> Handler 的映射
HandlerAdapter 适配不同的 Handler 类型
Handler 处理器(Controller)
ViewResolver 视图解析
View 视图渲染

请求处理流程

HTTP Request
|
v
DispatcherServlet.doDispatch()
|
v
1. 调用 HandlerMapping 获取 HandlerExecutionChain
├── Handler(Controller 方法)
└── Interceptor 列表
|
v
2. 调用 HandlerAdapter 执行 Handler
|
v
3. 参数解析(HandlerMethodArgumentResolver)
├── @RequestParam
├── @PathVariable
├── @RequestBody
└── ...
|
v
4. 执行 Controller 方法
|
v
5. 返回值处理(HandlerMethodReturnValueHandler)
├── @ResponseBody -> HttpMessageConverter
├── String -> View 名称
└── ModelAndView
|
v
6. 执行 Interceptor 的 postHandle
|
v
7. 视图解析和渲染(非 @ResponseBody)
|
v
8. 执行 Interceptor 的 afterCompletion
|
v
HTTP Response

DispatcherServlet 源码分析

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;

try {
ModelAndView mv = null;
Exception dispatchException = null;

try {
// 1. 检查文件上传
processedRequest = checkMultipart(request);

// 2. 获取 HandlerExecutionChain
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}

// 3. 获取 HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 4. 执行 Interceptor preHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return; // preHandle 返回 false,中断处理
}

// 5. 执行 Handler
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

// 6. 应用默认视图名
applyDefaultViewName(processedRequest, mv);

// 7. 执行 Interceptor postHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}

// 8. 处理结果(视图渲染或异常处理)
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
finally {
// 清理资源
}
}

HandlerMapping

常见实现

HandlerMapping
├── BeanNameUrlHandlerMapping # 根据 Bean 名称映射(旧)
├── SimpleUrlHandlerMapping # 简单 URL 映射
└── RequestMappingHandlerMapping # @RequestMapping 注解映射(默认)

RequestMappingHandlerMapping

@Controller
@RequestMapping("/users")
public class UserController {

@GetMapping("/{id}")
@ResponseBody
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
}

映射信息存储

// 启动时扫描所有 @RequestMapping 注解
// 存储到 MappingRegistry
Map<T, HandlerMethod> mappingLookup // URL -> HandlerMethod
Map<T, MappingRegistration<T>> registry // 完整注册信息

HandlerAdapter

常见实现

HandlerAdapter
├── HttpRequestHandlerAdapter # HttpRequestHandler
├── SimpleControllerHandlerAdapter # Controller 接口
├── SimpleServletHandlerAdapter # Servlet
└── RequestMappingHandlerAdapter # @RequestMapping(默认)

RequestMappingHandlerAdapter

// 执行流程
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {

HandlerMethod handlerMethod = (HandlerMethod) handler;

// 1. 创建 WebDataBinderFactory(数据绑定)
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);

// 2. 创建 ModelFactory(模型管理)
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

// 3. 解析参数
Object[] args = resolveArguments(request, handlerMethod, binderFactory);

// 4. 执行方法
Object returnValue = handlerMethod.invoke(args);

// 5. 处理返回值
return handleReturnValue(returnValue, handlerMethod);
}

参数解析

常用参数解析器

注解/类型 解析器 说明
@RequestParam RequestParamMethodArgumentResolver 请求参数
@PathVariable PathVariableMethodArgumentResolver URL 路径变量
@RequestBody RequestResponseBodyMethodProcessor JSON/XML 反序列化
@ModelAttribute ServletModelAttributeMethodProcessor 表单对象绑定
HttpServletRequest ServletRequestMethodArgumentResolver Servlet 请求
@RequestHeader RequestHeaderMethodArgumentResolver 请求头

自定义参数解析器

public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(CurrentUser.class)
&& parameter.getParameterType() == User.class;
}

@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
// 从 Session/Token 获取当前用户
return UserContext.getCurrentUser();
}
}

// 注册
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CurrentUserArgumentResolver());
}
}

返回值处理

常用返回值处理器

返回值类型 处理器 说明
@ResponseBody RequestResponseBodyMethodProcessor JSON/XML 序列化
String ViewNameMethodReturnValueHandler 视图名称
ModelAndView ModelAndViewMethodReturnValueHandler 模型和视图
void ViewNameMethodReturnValueHandler 默认视图

HttpMessageConverter

@ResponseBody
|
v
RequestResponseBodyMethodProcessor
|
v
HttpMessageConverter
├── MappingJackson2HttpMessageConverter # JSON
├── MappingJackson2XmlHttpMessageConverter # XML
└── StringHttpMessageConverter # String

Interceptor 执行顺序

@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor()) // 顺序 1
.addPathPatterns("/**")
.excludePathPatterns("/login");

registry.addInterceptor(new LogInterceptor()) // 顺序 2
.addPathPatterns("/**");
}
}
请求
|
├── AuthInterceptor.preHandle() -> true
│ ├── LogInterceptor.preHandle() -> true
│ │ ├── Controller 执行
│ │ ├── LogInterceptor.postHandle()
│ ├── AuthInterceptor.postHandle()
│ ├── 视图渲染
│ ├── LogInterceptor.afterCompletion()
├── AuthInterceptor.afterCompletion()

异常处理

@ExceptionHandler

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(BusinessException.class)
@ResponseBody
public Result<?> handleBusiness(BusinessException e) {
return Result.fail(e.getCode(), e.getMessage());
}

@ExceptionHandler(Exception.class)
@ResponseBody
public Result<?> handleException(Exception e) {
return Result.fail(500, "系统错误");
}
}

异常处理流程

Controller 抛出异常
|
v
DispatcherServlet.processHandlerException()
|
v
遍历 HandlerExceptionResolver
├── ExceptionHandlerExceptionResolver # @ExceptionHandler
├── ResponseStatusExceptionResolver # @ResponseStatus
└── DefaultHandlerExceptionResolver # Spring 默认异常
|
v
生成 ModelAndView 或重新抛出

总结

Spring MVC 的请求处理流程清晰分层:

  1. DispatcherServlet:统一入口
  2. HandlerMapping:路由匹配
  3. HandlerAdapter:适配执行
  4. ArgumentResolver:参数解析
  5. Controller:业务处理
  6. ReturnValueHandler:返回值处理
  7. ViewResolver:视图解析
  8. Interceptor:横切处理

理解这个流程,可以灵活扩展 Spring MVC 的功能,如自定义参数解析、返回值处理、异常处理等。


   转载规则


《Spring MVC请求处理流程》 小乐 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录