一、Spring MVC 核心认知:从设计哲学到核心组件​

1.1 框架定位与设计优势​

Spring MVC 是 Spring Framework 的核心 Web 模块,基于 MVC 设计模式实现,专为解决 Java Web 开发中的请求处理、路由分发、视图渲染等核心问题而生。其成为行业标准的三大核心优势:​

  • 前端控制器模式:通过DispatcherServlet统一接收所有请求,避免组件分散耦合,简化请求入口管理;​
  • 约定优于配置:注解驱动(如@Controller、@RequestMapping)替代复杂 XML 配置,大幅提升开发效率;​
  • 高度可扩展架构:核心组件均为接口驱动设计,支持自定义实现(如自定义拦截器、参数解析器),适配各类业务场景。​

1.2 核心组件详解(面试高频考点)​

Spring MVC 的请求处理依赖「组件协同体系」,每个组件各司其职,是理解工作流程的基础:​

组件名称​

核心职责​

常用实现类​

面试关联问题​

DispatcherServlet​

中央调度器,统一接收请求、协调所有组件,Spring MVC 入口​

DispatcherServlet(继承 HttpServlet)​

1. 前端控制器的作用?>2. 如何配置 DispatcherServlet?​

HandlerMapping​

根据 URL + 请求方式,匹配对应的 Controller 方法 + 拦截器,返回 HandlerExecutionChain​

RequestMappingHandlerMapping​

1. 注解式映射的实现原理?>2. 如何自定义 URL 匹配规则?​

HandlerAdapter​

适配不同类型处理器,调用目标方法(解决 "如何调用 Controller 方法" 问题)​

RequestMappingHandlerAdapter​

1. 适配器模式在 Spring MVC 中的应用?. 参数绑定的底层逻辑?​

HandlerInterceptor​

请求处理的增强器,支持预处理 / 后处理 / 资源清理​

自定义实现 HandlerInterceptor 接口​

1. 拦截器的执行顺序?2. 拦截器与过滤器的区别?​

ModelAndView​

封装处理结果:视图名称 + 模型数据​

ModelAndView​

1. Model 与 ModelMap 的区别?2. 如何返回 JSON 数据?​

ViewResolver​

将逻辑视图名解析为物理视图(如 JSP/Thymeleaf)​

InternalResourceViewResolver​

1. 视图解析器的配置方式?2. 如何支持多视图技术?​

HandlerExceptionResolver​

统一捕获请求处理中的异常,返回标准化响应​

ExceptionHandlerExceptionResolver​

1. 全局异常处理的实现方式? @ExceptionHandler 的作用?​

二、请求处理全流程:10 步拆解(含源码关联)​

以用户访问GET /user/get?id=1为例,结合 Spring 5.3.x 源码,详解从 HTTP 请求到响应的完整链路:​

步骤 1:请求到达 Web 服务器,转发至 DispatcherServlet​

  • HTTP 请求首先被 Tomcat 接收,根据web.xml或 Spring Boot 自动配置(默认拦截所有非静态资源),将请求转发给DispatcherServlet;​
  • 核心源码:DispatcherServlet#doDispatch()方法,所有请求最终都会进入该方法,是流程的入口。​

步骤 2:初始化请求上下文​

  • 在doDispatch()中,首先封装请求 / 响应对象(HttpServletRequestWrapper),初始化国际化上下文(LocaleContext)、主题上下文(ThemeContext);​
  • 关键逻辑:检查是否为文件上传请求,若为则封装为MultipartHttpServletRequest。​

步骤 3:HandlerMapping 查找处理器执行链​

  • DispatcherServlet调用getHandler(request)方法,通过HandlerMapping匹配对应的 Controller 方法;​
  • 核心逻辑:RequestMappingHandlerMapping扫描@Controller和@RequestMapping注解,建立 URL 与方法的映射关系,返回包含目标方法和拦截器的HandlerExecutionChain;​
  • 面试点:若未找到匹配处理器,会触发noHandlerFound(),返回 404 响应。​

步骤 4:HandlerAdapter 适配处理器​

  • DispatcherServlet调用getHandlerAdapter(handler),获取适配当前处理器的HandlerAdapter(注解式 Controller 对应RequestMappingHandlerAdapter);​
  • 核心工作:解析方法签名(参数注解、返回值类型),准备参数绑定、数据验证、消息转换(JSON/XML)等前置工作。​

步骤 5:拦截器预处理(preHandle)​

  • 执行HandlerExecutionChain中的拦截器preHandle()方法(按注册顺序执行);​
  • 关键规则:若任一拦截器返回false,则中断流程,直接返回响应(常用作登录校验、权限控制);​
  • 源码关联:HandlerExecutionChain#applyPreHandle()。​

步骤 6:调用 Controller 方法,执行业务逻辑​

  • HandlerAdapter调用handle()方法,通过反射执行目标 Controller 方法,完成参数绑定(如@RequestParam接收id=1)、业务逻辑处理(调用 Service/DAO 层);​
  • 核心逻辑:参数绑定由ArgumentResolver完成,支持@PathVariable、@RequestBody等多种绑定方式;​
  • 结果返回:若返回ModelAndView则进入视图渲染流程,若加@ResponseBody则直接返回 JSON 数据。​

步骤 7:拦截器后处理(postHandle)​

  • Controller 方法执行完成后,执行拦截器postHandle()方法(按注册顺序逆序执行);​
  • 核心作用:可修改ModelAndView对象(如添加全局数据),仅在视图渲染前执行。​

步骤 8:视图解析(ViewResolver)​

  • 若返回ModelAndView,DispatcherServlet调用resolveViewName(),通过ViewResolver将逻辑视图名(如 "userDetail")解析为物理视图(如/WEB-INF/views/userDetail.jsp);​
  • 多视图支持:若配置多个视图解析器,按优先级顺序尝试解析。​

步骤 9:视图渲染与响应返回​

  • View#render()方法将模型数据(如用户信息)合并到视图模板,生成 HTML/JSON 等响应内容;​
  • 若为 RESTful 接口(@RestController),则跳过视图解析,直接通过HttpMessageConverter将返回对象序列化为 JSON。​

步骤 10:拦截器完成后处理(afterCompletion)​

  • 无论请求成功或失败,都会执行拦截器afterCompletion()方法(按 preHandle 成功顺序逆序执行);​
  • 核心作用:资源清理(如关闭流、释放连接)。​

流程总结:核心链路公式​:

请求 → DispatcherServlet → HandlerMapping → HandlerExecutionChain → 
HandlerAdapter → 拦截器preHandle → Controller → 拦截器postHandle → 
ViewResolver → 视图渲染 → 拦截器afterCompletion → 响应

三、面试高频问题与实战避坑​

3.1 核心面试题(含标准答案)​

  1. Spring MVC 与 Spring Boot 的关系?​
  • 答:Spring MVC 是 Web 开发框架(核心是请求处理),Spring Boot 是快速开发脚手架;Spring Boot 通过自动配置(如DispatcherServletAutoConfiguration)简化 Spring MVC 的配置,无需手动编写 XML,实现 "开箱即用"。​
  1. 拦截器与过滤器的区别?​

维度​

拦截器(HandlerInterceptor)​

过滤器(Filter)​

归属​

Spring MVC 框架​

Servlet 规范​

执行时机​

DispatcherServlet 之后,Controller 之前​

请求进入 Tomcat 后,DispatcherServlet 之前​

功能范围​

仅拦截 Spring MVC 管理的请求​

拦截所有 Web 请求(静态资源、JSP 等)​

依赖环境​

依赖 Spring 容器​

无依赖,纯 Java EE 组件​

核心方法​

preHandle/postHandle/afterCompletion​

init/doFilter/destroy​

  1. 如何实现 RESTful API?​
  • 答:1. 使用@RestController(等价于@Controller + @ResponseBody);2. 用@GetMapping/@PostMapping/@DeleteMapping等注解绑定 HTTP 方法;3. 通过@PathVariable接收 URL 路径参数;4. 利用@RequestBody/@ResponseBody实现 JSON 序列化 / 反序列化。​
  1. 参数接收失败的常见原因?​
  • 答:1. 参数名与请求参数不一致(未加@RequestParam指定名称);2. 数据类型不匹配(如 String 转 Integer 失败);3. 复杂对象未加@RequestBody(JSON 请求);4. 请求编码问题(未配置 CharacterEncodingFilter)。​
  1. 全局异常处理的 3 种方式?​
  • 答:1. 自定义@ControllerAdvice + @ExceptionHandler;2. 实现HandlerExceptionResolver接口;3. 配置SimpleMappingExceptionResolver(XML 方式)。​

3.2 实战避坑指南​

  1. 拦截器不生效?​
  • 排查点:1. 拦截器未注册到 Spring 容器;2. 拦截路径配置错误(如/**写成/*);3. Spring Boot 2.x + 需通过addInterceptors()注册,而非 XML 配置。​
  1. 请求乱码问题?​
  • 解决方案:配置CharacterEncodingFilter,强制设置请求 / 响应编码为 UTF-8:​
@Bean
public FilterRegistrationBean> characterEncodingFilter() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    filter.setForceEncoding(true);
    FilterRegistrationBean<CharacterEncodingFilter> registration = new FilterRegistrationBean);
    registration.addUrlPatterns("/*");
    return registration;
}
  1. 静态资源被 DispatcherServlet 拦截?​
  • 解决方案:Spring Boot 中通过application.yml配置静态资源路径:​
spring:
  mvc:
    static-path-pattern: /static/**

三、总结:核心要点速记​

  1. 核心思想:以DispatcherServlet为中枢,通过组件解耦实现请求处理的标准化流程;​
  1. 流程关键:记住 "映射→适配→执行→渲染" 四大环节,拦截器贯穿全程;​
  1. 面试重点:组件作用、流程细节、设计模式应用(适配器 / 前端控制器)、实战问题排查;​
  1. 学习建议:结合源码阅读doDispatch()方法,通过 DEBUG 日志(开启org.springframework.web.servlet包 DEBUG 级别)观察流程流转。​

掌握以上内容,既能应对面试中的原理性问题,也能快速定位开发中的实际故障,真正做到 "知其然且知其所以然"。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐