bigywater.tech
Spring · 122

Gateway 全局过滤器的顺序

自己写的 GlobalFilter 会在什么时候执行?路由里的 AddRequestHeader 和全局过滤器谁先谁后?default-filters 和路由自己的过滤器顺序如何?鉴权过滤器直接返回 401 之后后面的还会执行吗?这篇在 Spring Cloud Gateway 5.0.3 上让 GlobalFilter 报告自己在每一层看到了什么。

order 1 先全局
全局过滤器 order 1 与路由过滤器 order 1 相遇时,全局的先执行
2147483647
NettyRoutingFilter 的 order,真正发请求的过滤器排在最后
post 仍执行
过滤器短路返回 401 之后,前面已经 pre 过的过滤器的 post 依然会执行

交错顺序

实测 · 本机执行输出
  GET /t/x → 200
  pre  g-5(order -5)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头
  pre  g0(order 0)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头
  pre  g1(order 1)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头
  pre  g2(order 2)  已经看到 X-A=[1]
  pre  g3(order 3)  已经看到 X-A=[1] X-B=[2]
  post g3(order 3)
  post g2(order 2)
  post g1(order 1)
  post g0(order 0)
  post g-5(order -5)
  /actuator/gateway/globalfilters(内置的全局过滤器与它们的 order):
    order  -2147483648  RemoveCachedBodyFilter
    order  -2147482648  AdaptCachedBodyGlobalFilter
    order           -5  Main$F
    order           -1  NettyWriteResponseFilter
    order            0  GatewayMetricsFilter
    order            0  Main$F
    order            0  ForwardPathFilter
    order            1  Main$F
    order            2  Main$F
    order            3  Main$F
    order        10000  RouteToRequestUrlFilter
    order        10150  GatewayNoLoadBalancerClientAutoConfiguration$NoLoadBalancerClientFilter
    order   2147483646  WebsocketRoutingFilter
    order   2147483647  ForwardRoutingFilter
    order   2147483647  NettyRoutingFilter
  /actuator/gateway/routes 里 r1 的路由过滤器:[["[[AddRequestHeader X-A = '1'], order = 1]", "[[AddRequestHeader X-B = '2'], order = 2]"]]

pre 正序、post 倒序;路由过滤器按位置从 1 编号,与全局过滤器一起排序。

default-filters

实测 · 本机执行输出
  default-filters 配 AddRequestHeader=X-Z, d,路由自己配 AddRequestHeader=X-Z, r,/actuator/gateway/routes 里这条路由的过滤器:[["[[AddRequestHeader X-Z = 'd'], order = 1]", "[[AddRequestHeader X-Z = 'r'], order = 1]"]]
  到 order 3 的全局过滤器时,X-Z 的值(按添加的先后顺序)= [d, r]

与路由自己的过滤器各自从 1 编号,默认的先执行。

同 order

实测 · 本机执行输出
  tieA、tieB、tieC 的 order 都是 7,bean 的声明顺序 A、B、C:pre 的顺序 = tieA → tieB → tieC

这次按 bean 声明顺序,但没有明确保证。

短路

实测 · 本机执行输出
  带 X-Block → 网关返回 401,后端收到 0 次请求;日志:pre  g-5(order -5)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头 | pre  g0(order 0)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头 | pre  g1(order 1)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头 | pre  g2(order 2)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头 | pre  g3(order 3)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头 | pre  block(order 4)  还没有看到任何 X-A/X-B/X-D/X-R/X-Z 头 | block 过滤器不调用 chain.filter,直接返回 401 | post g3(order 3) | post g2(order 2) | post g1(order 1) | post g0(order 0) | post g-5(order -5)
  不带 X-Block → 网关返回 200,后端收到 1 次请求

不调用 chain.filter 请求就到此为止,后端收不到。

分步演示

全局过滤器顺序
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动。5 个自己写的 GlobalFilter 在 pre 与 post 打印日志,用 AddRequestHeader 路由过滤器作为「是否已执行」的探针;内置过滤器的 order 来自 /actuator/gateway/globalfilters;后端是 Python 线程里的 HTTP 服务
    • 没有验证:同 order 过滤器的执行顺序是否有文档保证(只测了一个配置类里声明三个 bean);自定义 GatewayFilterFactory 的 order;OrderedGatewayFilter 的显式 order;全局过滤器里读取请求体(第 123 篇讨论阻塞);GlobalFilter 在异常情况下 post 部分的行为;GatewayMetricsFilter 的实际作用;Server MVC 版的过滤器模型
    京ICP备2026067502号-1京公网安备11010502063487号