Spring MVC 执行流程?

2025年 阅读约 15 分钟 面试指南 · Spring Boot

深入解析Spring MVC执行流程:DispatcherServlet核心调度、HandlerMapping处理器映射、HandlerAdapter适配器、视图解析、拦截器链、异常解析器,附面试模拟问答。

一句话总结

Spring MVC 执行流程核心:DispatcherServlet 作为前端控制器统一调度。流程:请求 → DispatcherServlet → HandlerMapping(找到处理器)→ HandlerAdapter(执行处理器)→ Controller 处理 → 返回 ModelAndView → ViewResolver(解析视图)→ 渲染响应。关键组件:HandlerMapping(URL 映射到 Controller)、HandlerAdapter(适配不同类型的 Controller)、HandlerInterceptor(拦截器链,前置 → Controller → 后置 → 完成)、ViewResolver(逻辑视图名 → 物理视图)。

初级理解

执行流程概览

# Spring MVC 请求处理流程 # 1. 用户发送请求 → DispatcherServlet(前端控制器) # 2. DispatcherServlet 调用 HandlerMapping # 3. HandlerMapping 返回 HandlerExecutionChain(Handler + 拦截器) # 4. DispatcherServlet 调用 HandlerAdapter # 5. HandlerAdapter 执行 Handler(Controller) # 6. Controller 返回 ModelAndView # 7. DispatcherServlet 调用 ViewResolver # 8. ViewResolver 返回 View # 9. View 渲染,返回响应 # 核心组件 # DispatcherServlet:前端控制器,统一调度 # HandlerMapping:处理器映射,URL → Controller # HandlerAdapter:处理器适配器,适配不同类型的 Controller # HandlerInterceptor:拦截器 # ViewResolver:视图解析器 # View:视图

中级深入

DispatcherServlet 源码分析

# DispatcherServlet.doDispatch() 核心源码 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; try { // 1. 文件上传处理 processedRequest = checkMultipart(request); // 2. 获取 Handler(通过 HandlerMapping) mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 3. 获取 HandlerAdapter HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 4. 执行拦截器 preHandle if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; // 拦截器返回 false,停止 } // 5. 执行 Handler(Controller 方法) ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 6. 执行拦截器 postHandle mappedHandler.applyPostHandle(processedRequest, response, mv); // 7. 处理视图 processDispatchResult(processedRequest, response, mappedHandler, mv); } finally { // 8. 执行拦截器 afterCompletion mappedHandler.triggerAfterCompletion(request, response, null); } }

拦截器 vs 过滤器

对比维度拦截器(Interceptor)过滤器(Filter)
归属Spring MVCServlet 容器
执行顺序Filter → Interceptor先于 Interceptor
能力可获取 Controller、参数只能获取 Request/Response
适用场景权限、日志(业务相关)编码、跨域(通用)

高级拓展

HandlerMapping 和 HandlerAdapter

# HandlerMapping 实现类 # RequestMappingHandlerMapping:处理 @RequestMapping 注解 # BeanNameUrlHandlerMapping:处理 Bean name 以 "/" 开头的 # SimpleUrlHandlerMapping:直接配置 URL 映射 # HandlerAdapter 实现类 # RequestMappingHandlerAdapter:处理 @RequestMapping 方法 # HttpRequestHandlerAdapter:处理 HttpRequestHandler # SimpleControllerHandlerAdapter:处理 Controller 接口 # 为什么需要 HandlerAdapter? # 不同类型的 Controller 执行方式不同 # 通过适配器模式统一调用

@ResponseBody 和 @RestController

# @ResponseBody 原理 # 1. Controller 方法标注 @ResponseBody # 2. 返回值不走视图解析 # 3. 通过 HttpMessageConverter 将返回值写入 Response Body # 4. 默认使用 Jackson 将对象转为 JSON # @RestController = @Controller + @ResponseBody @RestController public class UserController { @GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { return userService.getById(id); // 自动转 JSON } } # HttpMessageConverter 常用实现 # MappingJackson2HttpMessageConverter:JSON 转换 # StringHttpMessageConverter:字符串转换 # ByteArrayHttpMessageConverter:字节数组转换

实战场景

场景:自定义拦截器

# 1. 定义拦截器 @Component public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (token == null) { response.setStatus(401); return false; // 拦截 } return true; // 放行 } } # 2. 注册拦截器 @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns("/api/**") // 拦截路径 .excludePathPatterns("/api/login"); // 排除路径 } }

面试模拟

面试官:Spring MVC 的执行流程是怎样的?

你:DispatcherServlet 接收请求 → HandlerMapping 找到 Handler → HandlerAdapter 执行 Handler → Controller 返回 ModelAndView → ViewResolver 解析视图 → 渲染响应。拦截器在 Handler 前后执行(preHandle → Controller → postHandle → afterCompletion)。

面试官:拦截器和过滤器有什么区别?

你:过滤器是 Servlet 容器层面的,先于拦截器执行,只能获取 Request/Response;拦截器是 Spring MVC 层面的,可以获取 Controller 和方法参数。过滤器适合编码、跨域等通用处理,拦截器适合权限、日志等业务处理。