Skip to content

Spring MVC

Web 与框架 🔥 高频

💡 核心要点

Spring MVC 是 Spring 对 Servlet 的封装,以 DispatcherServlet 为核心前端控制器,用注解驱动代替手写 Servlet。理解一个请求从进入到返回的完整流程是掌握 Spring MVC 的关键——面试几乎必问。


整体架构

HTTP 请求

Filter 链(Servlet 层:编码、CORS、安全)

DispatcherServlet(前端控制器,Spring MVC 入口)
  ├── HandlerMapping(找到哪个 Controller 方法处理)
  ├── HandlerAdapter(适配不同类型的 Handler)

Interceptor 链 preHandle(Spring MVC 层拦截)

Controller 方法执行
  ├── 参数绑定(@RequestParam / @PathVariable / @RequestBody)
  ├── 数据校验(@Valid / @Validated)

返回值处理
  ├── @ResponseBody → HttpMessageConverter → JSON
  ├── 返回视图名 → ViewResolver → 渲染 HTML

Interceptor 链 postHandle / afterCompletion

HTTP 响应

核心概念速查

概念职责面试要点
DispatcherServlet前端控制器,分发所有请求请求处理流程的起点
HandlerMappingURL → Controller 方法的映射RequestMappingHandlerMapping
HandlerAdapter调用 Handler 的适配器统一不同类型 Handler 的调用方式
InterceptorHandler 前后的拦截逻辑与 Filter 的区别(Servlet 层 vs MVC 层)
HttpMessageConverter请求/响应体的序列化反序列化Jackson 处理 JSON
@ControllerAdvice全局异常/数据绑定处理@ExceptionHandler 集中处理异常

Filter vs Interceptor 对比

这是面试高频对比题:

对比项FilterInterceptor
所属层Servlet 规范Spring MVC
执行时机DispatcherServlet 之前DispatcherServlet 之后、Controller 之前
能否访问 Spring 容器不能(除非特殊处理)能(本身是 Spring Bean)
能否获取 Handler 信息不能能(参数包含 HandlerMethod)
典型用途编码转换、CORS、安全过滤权限校验、日志、登录检查

执行顺序:Filter → DispatcherServlet → Interceptor preHandle → Controller → Interceptor postHandle → Interceptor afterCompletion → Filter

虚拟线程下的 Spring MVC(Boot 3.2+ 必读)

⚠️ 2026 高频追问

"Spring MVC 加了虚拟线程是不是就和 WebFlux 一样了?" —— 不一样。MVC 仍是同步阻塞编程模型,虚拟线程只是把"每请求一线程"的代价从 MB 级降到 KB 级,让传统写法直接吃到高并发红利,但编程模型完全不变

主题平台线程时代虚拟线程时代
并发上限几百到几千(线程栈 1MB)几十万(虚拟线程栈 KB 级)
ThreadLocal安全且高效仍可用,但要警惕泄漏(频繁创建销毁)
SecurityContextHolderThreadLocal 实现,正常仍工作,但 @Async 跨线程需显式传
synchronized普通锁触发 Pinning(JDK 24+ 已修复多数)
RequestContextHolderThreadLocal仍生效,单请求生命周期内安全
阻塞 IO(JDBC / HttpClient)占线程释放载体线程,吞吐量飞跃

一行开启

yaml
spring:
  threads:
    virtual:
      enabled: true   # Boot 3.2+,Tomcat / @Async / Scheduled 全部走虚拟线程

心智模型:「JDK 21 + Boot 3.2 后,'Servlet 容器扛不住高并发'这个老论据已经站不住脚——WebFlux 的相对优势主要剩'流式数据' + '背压控制'」。详见 Spring WebFlux · 虚拟线程时代的选型

HandlerExceptionResolver:异常处理责任链

@ControllerAdvice + @ExceptionHandler 背后是一条 HandlerExceptionResolver 链,按顺序匹配,匹配成功就停止:

异常抛出 → resolveException 责任链 ──┐
  ① ExceptionHandlerExceptionResolver  ← @ExceptionHandler(最常用)
  ② ResponseStatusExceptionResolver    ← @ResponseStatus(含 ResponseStatusException)
  ③ DefaultHandlerExceptionResolver    ← Spring 内置(如 HttpMessageNotReadable → 400)
  ④ 自定义 HandlerExceptionResolver
Resolver触发典型场景
ExceptionHandlerExceptionResolver@ExceptionHandler 方法匹配异常类型业务异常 → 自定义 JSON 错误体
ResponseStatusExceptionResolver异常类标了 @ResponseStatus 或抛 ResponseStatusException简单的"业务码 + HTTP 码"映射
DefaultHandlerExceptionResolverSpring 框架自身的 30+ 种异常MethodArgumentNotValidException → 400
自定义实现 HandlerExceptionResolver + @Order接入告警、统一日志

ProblemDetail(Spring 6 / Boot 3):官方推荐用 RFC 9457 标准错误响应:

java
@ExceptionHandler(BusinessException.class)
ProblemDetail handle(BusinessException ex) {
    var pd = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, ex.getMessage());
    pd.setProperty("errorCode", ex.getCode());
    pd.setProperty("traceId", MDC.get("traceId"));
    return pd;
}

详细专题

专题核心知识点面试频率详细页面
请求处理流程DispatcherServlet 完整流程、拦截器链、参数绑定、@Valid 校验、全局异常处理🔥🔥🔥请求处理流程
RESTful APIREST 六大原则、HTTP 方法语义、状态码规范、版本管理、认证方式🔥🔥🔥RESTful API
Spring WebFluxMono/Flux、响应式编程、Event Loop、R2DBC、SSE/WebSocket、与 MVC 对比🔥🔥Spring WebFlux

面试常问 & 怎么答

Q1: Spring MVC 的请求处理流程?

请求进入 DispatcherServlet → HandlerMapping 找到对应的 Handler(Controller 方法)→ HandlerAdapter 执行 Handler → 返回 ModelAndView → ViewResolver 解析视图 → 渲染响应。前后端分离下不走 ViewResolver,直接通过 @ResponseBody 返回 JSON。

Q2: 拦截器和 Filter 的区别?

Filter 是 Servlet 规范的,在 DispatcherServlet 之前执行,作用于所有请求;Interceptor 是 Spring MVC 的,在 Handler 前后执行,可以访问 Spring 容器。执行顺序:Filter → DispatcherServlet → Interceptor → Controller。

Q3: @Controller 和 @RestController 的区别?

@RestController = @Controller + @ResponseBody。@Controller 的方法默认返回视图名称;@RestController 的方法直接返回数据(JSON),不走 ViewResolver。前后端分离项目统一用 @RestController。

Q4: 参数校验怎么做?@Valid 和 @Validated 的区别?

使用 JSR-303 注解(@NotNull、@Size 等)标注字段,Controller 参数前加 @Valid 或 @Validated 触发校验。区别:@Valid 是 JSR 标准注解,支持嵌套校验;@Validated 是 Spring 扩展,支持分组校验(groups)。面试中答出"分组校验"这个区别就够了。

看到什么就先想到这类

  • 出现 Controller、@RequestMapping、DispatcherServlet → 请求处理流程
  • 出现拦截器、HandlerInterceptor → Filter vs Interceptor 对比
  • 出现参数校验、@Valid、@Validated → 数据绑定与校验
  • 出现全局异常处理、@ControllerAdvice → 异常处理机制
  • 出现 RESTful、HTTP 方法、状态码 → REST 设计原则