Spring MVC 工作原理
Spring MVC 基于传统的 Servlet API,采用同步阻塞式模型,核心流程围绕前端控制器 DispatcherServlet 展开:
-
请求分发
客户端请求首先由
DispatcherServlet接收,根据请求路径匹配对应的HandlerMapping,确定目标控制器(Controller)。 -
处理器适配
HandlerAdapter调用控制器方法处理请求,期间可能涉及参数绑定(如@RequestParam)、模型填充(Model)等操作。 -
视图解析
控制器返回逻辑视图名后,
ViewResolver将其解析为实际视图(如 JSP、Thymeleaf),最终渲染响应返回客户端。 -
同步阻塞特性
每个请求占用一个线程(Tomcat 线程池),高并发时线程资源可能成为瓶颈,适合 CPU 密集型或依赖传统数据库的场景。
Spring WebFlux 工作原理
WebFlux 是响应式非阻塞框架,基于 Reactor 库和 Netty 等异步运行时,核心组件为 DispatcherHandler:
-
响应式请求处理
请求通过
DispatcherHandler路由到HandlerFunction,返回Mono或Flux流式响应,而非阻塞式等待结果。 -
事件循环模型
使用少量固定线程(如 Netty 的 EventLoop)处理 I/O 事件,通过回调或 Reactive Streams 实现非阻塞,适合高并发、延迟敏感场景。
-
函数式端点
除注解式控制器外,支持基于 Lambda 的函数式路由(
RouterFunction),提供更灵活的 API 组合方式。 -
背压支持
通过 Reactive Streams 规范实现消费者控制生产者速率(背压),避免数据溢出。
与传统实现方式的比较
-
线程模型差异
- 传统 Servlet:每个请求独占线程,线程数限制并发量。
- WebFlux:共享线程处理多请求,通过事件驱动减少资源消耗。
-
性能场景
- Spring MVC:适合长时间计算或阻塞式 I/O(如 JDBC)。
- WebFlux:优化高吞吐、短延迟场景(如微服务网关)。
-
编程范式
- MVC:命令式编程,直观易调试。
- WebFlux:声明式响应式编程,需适应异步链式调用。
-
生态兼容性
- MVC:强依赖 Servlet 容器(如 Tomcat),兼容传统库(如 Spring Data JPA)。
- WebFlux:需响应式驱动库(如 R2DBC、Reactive MongoDB)。
代码示例对比
Spring MVC 控制器
java
@RestController
public class MvcController {
@GetMapping("/data")
public String getData() {
return blockingDatabaseCall(); // 同步阻塞调用
}
}
WebFlux 控制器
java
@RestController
public class FluxController {
@GetMapping("/data")
public Mono<String> getData() {
return reactiveDatabaseCall(); // 返回 Mono 异步流
}
}
适用场景建议
- 选择 Spring MVC:项目依赖阻塞式库(如 JPA)、团队熟悉同步编程或需要兼容传统架构。
- 选择 WebFlux :系统要求高并发(如万级 QPS)、已使用响应式数据层或需要混合响应式与命令式(通过
Mono.fromCallable兼容阻塞代码)。