☰
Servlet 栈 vs WebFlux 栈:请求穿过哪些层
2026/10/2 20:10:27 网站建设 项目流程

Filter、Interceptor、AOP 谁先执行?跟着请求走一遍

看到这篇文章,让我想到了文章里讲的

Filter 属于 Servlet 规范,由 Tomcat 调用,跑在 DispatcherServlet 之前,所以在最外层,连静态资源的请求都会经过它。

Interceptor 属于 Spring MVC,由 DispatcherServlet 找到处理器之后调用。

AOP 是 Spring 的代理机制,作用在 Controller 方法的调用上,贴得最近。

延伸一下,就到了 Servlet 栈(Spring MVC)
WebFlux 栈(Spring WebFlux)。

Servlet 栈(Spring MVC)

┌─────────────────────────────────────────────────────────────┐ │ Client Request │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Web Container (Tomcat/Jetty) │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Filter Chain (javax.servlet.Filter) │ │ │ │ Filter1 → Filter2 → ... → FilterN │ │ │ └───────────────────────────┬───────────────────────────┘ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ DispatcherServlet │ │ │ │ ① HandlerMapping → 找到 HandlerMethod │ │ │ │ ② HandlerAdapter → 调用 Controller │ │ │ │ ③ HandlerInterceptor.preHandle() ◀── 注意这里 │ │ │ │ ④ 执行 @Controller 方法 │ │ │ │ ⑤ HandlerInterceptor.postHandle() ◀── 注意这里 │ │ │ │ ⑥ 渲染视图 / 写响应 │ │ │ │ ⑦ HandlerInterceptor.afterCompletion() ◀── 注意 │ │ │ └───────────────────────────┬───────────────────────────┘ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ HttpServletResponse (阻塞式输出) │ │ │ └───────────────────────────┬───────────────────────────┘ │ └──────────────────────────────┼──────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Client Response │ └─────────────────────────────────────────────────────────────┘

关键特征:Filter 是 Servlet 规范定义的,Interceptor 是 Spring MVC 框架自己加的。

WebFlux 栈(Spring WebFlux)

┌─────────────────────────────────────────────────────────────┐ │ Client Request │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Reactive Server (Netty / Undertow / Servlet3.1) │ │ (没有统一容器规范,各服务器私有 API) │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ HttpHandler (Spring 适配层,屏蔽服务器差异) │ │ ServerHttpRequest + ServerHttpResponse → Mono<Void> │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ WebFilter Chain (org.springframework.web.server.) │ │ WebFilter1 → WebFilter2 → ... → WebFilterN │ │ 对应 Servlet Filter,但是返回 Mono<Void>(响应式) │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ DispatcherHandler │ │ ① HandlerMapping → 找到 handler(不一定是 Method) │ │ ② HandlerAdapter → 调用 handler │ │ ③ 没有 HandlerInterceptor! │ │ ├── 前置逻辑 → 写在 WebFilter 里 │ │ ├── 后置逻辑 → 写在 WebFilter 里(或 doOnSuccess) │ │ └── 异常处理 → WebFilter 的 onErrorResume │ │ ④ Controller 返回 Mono / Flux │ │ ⑤ HandlerResultHandler → 序列化并写响应 │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ ServerHttpResponse(非阻塞、背压感知、流式写入) │ └─────────────────────────────┬───────────────────────────────┘ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Client Response │ └─────────────────────────────────────────────────────────────┘

关键特征:没有 Filter 规范、没有 Interceptor,一切靠WebFilter+Mono操作符链。

逐层对照表

层次

Servlet / Spring MVC

WebFlux / Reactive

规范层​

Servlet规范 (Jakarta EE)

无容器规范,只有Reactive Streams

服务器​

Tomcat / Jetty (Servlet 模式)

Netty / Undertow / Tomcat(3.1 NIO)

服务器→框架适配​

Servlet API 直接对接

HttpHandler适配层

全局前置/后置​

javax.servlet.Filter

org.springframework.web.server.WebFilter

中央调度器​

DispatcherServlet

DispatcherHandler

路由/映射​

HandlerMapping→HandlerMethod

HandlerMapping→ 任意 handler

处理器前后拦截​

✅HandlerInterceptor(3个回调)

❌ 没有,用WebFilter或Mono操作符

参数解析/返回值处理​

HandlerMethodArgumentResolver/HandlerMethodReturnValueHandler

HandlerAdapter+HandlerResultHandler

响应写入​

HttpServletResponse(阻塞)

ServerHttpResponse(非阻塞 + 背压)

异常处理​

@ExceptionHandler/HandlerExceptionResolver

@ExceptionHandler/WebExceptionHandler

一句话总结差异本质

Servlet 栈: 规范定义容器 → 容器定义 Filter → 框架加 Interceptor → 阻塞 I/O
WebFlux 栈: 无容器规范 → 框架自己适配服务器 → 只有 WebFilter → 响应式流 + 背压

三者(Undertow / Jetty / Tomcat)在 WebFlux 下的真实定位

服务器

WebFlux 使用方式

非阻塞纯度

说明

Netty​

Reactor Netty 直连

最高

EventLoop + 全链路响应式,WebFlux 默认

Undertow​

Undertow API 直连(非 Servlet)

高

XNIO 事件模型,适合响应式,轻量

Jetty​

Servlet 3.1 NIO 适配

中

能跑,但走 Servlet 非阻塞桥

Tomcat​

Servlet 3.1 NIO 适配

中

同上,线程池模型偏传统

Netty是响应式最好的,Undertow次之,其他的servlet容器最差。

  1. Undertow 严格说不算"次之",而是"和 Netty 同一档但生态弱一截"——它走的是 XNIO 事件模型,不是 Servlet 适配,非阻塞纯度其实很高。只是 Reactor Netty 跟 Spring WebFlux 是同一个团队(reactor 项目)出的,磨合最好、文档最全、踩坑最少。
  2. Tomcat/Jetty 不是"差",是"定位不同"——它们本来就是为 Servlet 同步模型设计的,响应式是后来硬桥上去的。能跑,但线程模型、内存占用、长连接表现都拼不过原生响应式底座。

所以更准确的说法是:

Netty ≈ Undertow(原生响应式底座)> Tomcat ≈ Jetty(Servlet 适配桥接)

选谁就看你场景——新项目无历史包袱直接 Netty;已有 Undertow 技术栈直接上 WebFlux 完全没问题;老项目想试水响应式又不想换容器,Tomcat/Jetty 也能跑,别指望性能飞跃就行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询