☰
Spring Cloud Gateway过滤器体系详解:GatewayFilter核心机制与源码拆解
2026/10/16 4:06:42 网站建设 项目流程

Spring Cloud Gateway 的过滤器体系最劝退人的地方,就是类名极度相似:GatewayFilter、GatewayFilterFactory、GlobalFilter,再加上配置文件里那一串像AddRequestHeader这样的短名字,很容易让人绕晕。我之前有一段经历很典型:团队在做网关改造,我照着官方文档把十几个过滤器往配置里一贴,跑起来完全没问题,但某天线上出了个诡异的响应头重复问题,我盯着配置看了半天,愣是不知道该从哪里下手排查。那一刻我意识到,光会用不行,必须把这层抽象给啃透。所以这篇我来做一次集中梳理,把GatewayFilter这个层面的东西完整过一遍,顺便把它的装配链路和几个核心过滤器的源码拆给你看。

这一篇对应的是整个源码解析系列的过滤器部分,我把 4.1 这一节当作“总览 + 索引”来处理:先讲清楚 GatewayFilter 在整个架构里的位置,再把内置过滤器全部盘点一遍,接着走一遍从路由配置到过滤器链的完整装配链路,最后挑出三个最典型的过滤器做源码级的拆解。无论你是刚开始接触网关,还是已经在生产环境里用它做鉴权、限流、灰度,这篇文章都能帮你把“配置能跑”提升到“出问题知道去哪查”的层次。

1. 先认清 GatewayFilter 在 Gateway 过滤器体系里的坐标

很多同学混淆概念的根本原因,是把“过滤器”和“过滤器工厂”当成了一回事。我先把这两个东西掰开:GatewayFilter是一个真正作用于请求/响应的组件,它拿到ServerWebExchange和GatewayFilterChain,可以做前置处理、后置处理,然后调用chain.filter(exchange)把请求传递下去。而GatewayFilterFactory是生产过滤器实例的工厂,它接收一组配置参数,返回一个具体的GatewayFilter。

配置文件里的filters段,写的其实是工厂的名字,不是过滤器本身。

spring: cloud: gateway: routes: - id: user_route uri: lb://user-service predicates: - Path=/user/** filters: - AddRequestHeader=X-Request-Source, gw

这里AddRequestHeader看起来像过滤器,实际上它对应的是AddRequestHeaderGatewayFilterFactory。Spring Cloud Gateway 启动时,会拿着这个名字去容器里找对应的工厂 Bean,然后调用工厂的apply方法,用X-Request-Source和gw这两个参数生成一个匿名的GatewayFilter实例,最后塞进这条路由的过滤器链里。

这个设计很像现实世界里的“标准零件 + 工艺参数”:工厂是固定的,你给不同的参数,出来的是不同配置的零件。好处是显而易见的——如果每条路由的请求头都不一样,直接配置就能搞定,不需要为每种场景写一个新过滤器类。

再看GlobalFilter,它是另一种维度的过滤器:不需要绑定到某条路由,作用于网关收到的所有请求,比如负载均衡的ReactiveLoadBalancerClientFilter、转发请求的NettyRoutingFilter都属于这一类。你不需要为每条路由单独配置它们。

在FilteringWebHandler的handle方法中,两类过滤器会被合并成一条完整的执行链:

@Override public Mono<Void> handle(ServerWebExchange exchange) { Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); List<GatewayFilter> gatewayFilters = route.getFilters(); List<GatewayFilter> combined = combineGlobalFiltersAndGatewayFilters(gatewayFilters); ... return new DefaultGatewayFilterChain(combined).filter(exchange); }

combineGlobalFiltersAndGatewayFilters内部会先把两类过滤器拉平,再根据Ordered接口的getOrder()值排序。注意一个细节:所有GlobalFilter都被适配成了GatewayFilterAdapter,从类型上看它们也是GatewayFilter,所以整条链是统一处理的。

上面这段逻辑是整个过滤器体系的枢纽,多读几遍。它能解释很多线上问题,比如为什么某个过滤器明明写在配置中间,执行顺序却不按配置顺序来——因为最终排序是看getOrder(),不是看 YAML 里的先后顺序。

2. 内置 GatewayFilter 全量盘点与适用场景速查

Spring Cloud Gateway 内置的 GatewayFilter 数量不少,而且版本之间还在持续增加。我不打算把每个都长篇大论,而是给你一张速查表,按功能域分组。这里的名称统一写配置里用的短名,因为这才是你每天写配置时接触的东西。

功能域过滤器短名核心作用常用配置示例
请求头操作AddRequestHeader往请求里追加 HeaderAddRequestHeader=X-Request-Source, gw
请求头操作SetRequestHeader覆盖同名 Header 值SetRequestHeader=X-Request-Source, gw
请求头操作RemoveRequestHeader删除指定 HeaderRemoveRequestHeader=X-Request-Source
请求头操作MapRequestHeader从已有 Header 复制值到新 HeaderMapRequestHeader=X-From, X-To
请求参数AddRequestParameter追加 Query 参数AddRequestParameter=debug, true
请求参数RemoveRequestParameter删除 Query 参数RemoveRequestParameter=debug
路径操作StripPrefix转发前去掉前 N 段路径StripPrefix=1
路径操作PrefixPath为请求路径加前缀PrefixPath=/api
路径操作RewritePath用正则重写路径RewritePath=/old/(?<segment>.*), /new/$\{segment}
路径操作SetPath直接替换为模板路径SetPath=/new/{segment}
响应头操作AddResponseHeader往响应里追加 HeaderAddResponseHeader=X-Resp, ok
响应头操作SetResponseHeader覆盖响应 Header 值SetResponseHeader=X-Resp, ok
响应头操作RemoveResponseHeader删除响应 HeaderRemoveResponseHeader=X-Resp
响应头操作RewriteResponseHeader正则改写响应 Header 值RewriteResponseHeader=X-Resp, (.*), prefix-$1
响应头操作DedupeResponseHeader去重响应 HeaderDedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_FIRST
响应头操作RewriteLocationResponseHeader改写响应中的 LocationRewriteLocationResponseHeader=/old, /new, false
状态与跳转SetStatus设置响应状态码SetStatus=201
状态与跳转RedirectTo302 跳转RedirectTo=302, https://example.com
弹性能力Retry请求失败自动重试Retry=retries:3,statuses:SERVER_ERROR
弹性能力CircuitBreaker整合熔断器CircuitBreaker=name=cbA,fallbackUri=forward:/fallback
弹性能力FallbackHeaders把熔断异常写入请求头FallbackHeaders=executionExceptionTypeHeaderName=X-Ex-Type
请求体ModifyRequestBody修改请求体ModifyRequestBody=application/json, application/json, "#{...}"
响应体ModifyResponseBody修改响应体ModifyResponseBody=application/json, application/json, "#{...}"
限流RequestRateLimiter基于令牌桶限流RequestRateLimiter=redis-rate-limiter.replenishRate:1, redis-rate-limiter.burstCapacity:3
安全RequestSize限制请求体大小RequestSize=100KB
安全SecureHeaders追加安全响应头集合SecureHeaders
安全TokenRelay把 OAuth2 Token 传给下游TokenRelay
会话SaveSession转发前保存会话状态SaveSession
主机头PreserveHostHeader保留原始 HostPreserveHostHeader
主机头SetRequestHostHeader设置请求 HostSetRequestHostHeader=example.com

需要注意几点,这些都是实际项目中容易踩到的地方。

StripPrefix的中文文档描述经常让人误解。StripPrefix=1的意思是去掉原始路径的第一段,比如/order/list变成/list,而不是“去掉前缀字符串 order”。它按/分段计数,不是字符串替换。想按字符串替换请用RewritePath。

RewritePath里的正则和替换模板用的是 Java 的正则语法,$符号在 YAML 里要小心处理,否则会被当成变量插值处理。我一般建议把整段配置用单引号包裹,替换模板里的${segment}写成$\{segment}或者用一个临时变量绕开。

Retry的配置非常容易引发误伤。它默认重试的是 5xx 状态码和 GET 方法,这还好。但如果有人手动配置了statuses: BAD_REQUEST甚至methods: ALL,那在流量高峰期可能把本来能快速失败的错误请求反复打到下游,造成雪上加霜。后面我会单独讲它的源码,这里先记住:重试是有代价的,一定要控制重试次数和条件。

ModifyRequestBody和ModifyResponseBody的配置写起来最绕,因为它们支持 SpEL 表达式。官方示例里那串"#{...}"是在构造一个用于转换的类名,想用好必须自己写一个继承RewriteFunction的类,并在类上标注@Component,然后在表达式里引用它的 bean 名。这个过滤器我建议单独开一篇讲,这里先只给结论:别直接在配置里写复杂逻辑,表达式只是入口,真正的转换逻辑放到自定义组件里。

实际项目里最常见的组合是:StripPrefix+AddRequestHeader+RequestRateLimiter+Retry,分别对应路径改写、链路标识注入、限流兜底和瞬时故障容忍。这四个过滤器做基础骨架,大部分路由都够用。

3. 从 YAML 到过滤器链:GatewayFilter 的装配源码链路

这一节解决一个关键问题:那行 YAML 配置,到底是怎么一步步变成一个可执行的过滤器链的?这条链路涉及三个核心类,我按数据流方向走一遍,你跟着过一遍就能在脑子里建立完整的调用图。

3.1 路由定位器如何读取配置并构造过滤器实例

入口是RouteDefinitionRouteLocator。它负责读取RouteDefinition,也就是 YAML 里每条路由的原始定义,然后把它转换成真正可用的Route对象,Route里就包含了List<GatewayFilter>。

转换的核心方法在getFilters这个私有逻辑中,它会遍历路由定义里的filters列表,对每个短名执行以下关键步骤:

private GatewayFilter getGatewayFilter(RouteDefinition routeDefinition, FilterDefinition filterDefinition) { GatewayFilter gatewayFilter = null; String shortcutConfigurationPropertyName = null; if (filterDefinition.getName().contains(NAME_PREFIX)) { gatewayFilter = factoryMap.get(filterDefinition.getName()).apply(filterDefinition.getArgs()); } else { String factoryName = filterDefinition.getName() + NAME_PREFIX; // NAME_PREFIX = "GatewayFilterFactory" gatewayFilter = factoryMap.get(factoryName).apply(filterDefinition.getArgs()); } ... }

NAME_PREFIX就是GatewayFilterFactory这个后缀。如果你在配置里写AddRequestHeader,代码会去找AddRequestHeaderGatewayFilterFactory这个 bean;如果你写完整类名AddRequestHeaderGatewayFilterFactory,它也能直接按名字取。这里有个隐藏逻辑:factoryMap是 Spring 容器中所有GatewayFilterFactory类型的 bean 按名称组成的 Map,RouteDefinitionRouteLocator在初始化时注入,所以上面第二步能否成功,取决于你是否在容器里注册了对应工厂。

3.2 工厂的 apply 方法与快捷配置解析

找到工厂之后,调用apply(filterDefinition.getArgs()),args是过滤器参数的有序 Map。

这里就要聊 Spring Cloud Gateway 一个很巧妙的设计:快捷配置(shortcut configuration)。比如AddRequestHeader=X-Request-Source, gw这种用逗号分隔写法,底层会被解析成name和value两个参数。这是怎么做到的?

GatewayFilterFactory继承了ShortcutConfigurable接口,接口里有一个shortcutFieldOrder()方法。AddRequestHeaderGatewayFilterFactory的实现是:

@Override public List<String> shortcutFieldOrder() { return Arrays.asList(NAME_KEY, VALUE_KEY); // ["name", "value"] }

ConfigurationService会拿着这个顺序,把逗号分隔的值按顺序绑定到配置类的对应字段上。换句话说,ShortcutConfigurable定义的是“如何把紧凑的配置语法映射成一个结构化的配置对象”。

如果某天你想自定义一个过滤器工厂,且希望支持MyFilter=aaa, bbb, ccc这种写法,就必须正确实现shortcutFieldOrder,否则配置解析阶段就会报参数绑定错误。

3.3 过滤器链的组装与执行顺序

拿到所有过滤器之后,真正把链组装起来的逻辑在FilteringWebHandler里。前面贴过它的核心处理逻辑,这里我把它拆细一点,用伪代码展示它内部的实际步骤:

  1. 从 exchange 里取出当前路由对象Route
  2. 拿到路由自己的List<GatewayFilter>
  3. 从 Spring 容器中拿到所有GlobalFilter
  4. 把每个GlobalFilter包一层GatewayFilterAdapter,让它们的接口统一成GatewayFilter
  5. 把两组过滤器相加,排序(依据Ordered.getOrder())
  6. 构建DefaultGatewayFilterChain并执行

排序这一步容易让人踩坑。GatewayFilter如果没有实现Ordered,默认 order 为 0;而GlobalFilter的 order 通常都很大,比如NettyRoutingFilter的 order 是Integer.MAX_VALUE,ReactiveLoadBalancerClientFilter是LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150。所以正常情况下,先执行的是路由级的GatewayFilter,比如加头、改路径,然后才轮到负载均衡和真正的网络转发。

但如果你在自定义GatewayFilter时不小心给了一个很大的 order,比如Integer.MAX_VALUE - 1,那它可能会被排到NettyRoutingFilter之后才执行——这个时候请求可能已经发出去了,你再修改请求头就来不及了。这是一个非常隐蔽的问题,我在后面自定义部分会专门再提一次。

4. 拆三个有代表性的过滤器:AddRequestHeader、Retry 与 CircuitBreaker

内置过滤器有几十个,逐一细讲不现实。我挑三个刚好覆盖“简单、配置复杂、依赖外部组件”三种典型情况的,走一遍源码,你就能举一反三。

4.1 AddRequestHeaderGatewayFilterFactory:最标准的工厂样板

这个过滤器是所有内置工厂里最简单的,适合当入门教材。它的完整实现大致是:

public class AddRequestHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory<AddRequestHeaderGatewayFilterFactory.Config> { public AddRequestHeaderGatewayFilterFactory() { super(Config.class); } @Override public List<String> shortcutFieldOrder() { return Arrays.asList(NAME_KEY, VALUE_KEY); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest().mutate() .header(config.name, config.value) .build(); return chain.filter(exchange.mutate().request(request).build()); }; } public static class Config { private String name; private String value; // getter / setter 省略 } }

注意两个细节。第一,AbstractGatewayFilterFactory通过泛型指定了配置类,它在内部会完成“配置参数到配置对象”的绑定,工厂类本身只关心如何消费配置。第二,apply方法返回的是一个 lambda 形式的GatewayFilter,它捕获了config,这样每个路由的过滤器实例都有自己独立的配置副本,互不干扰。

这里有一个很多人没发现的小特性:当同一请求头被多次添加时,header(config.name, config.value)是追加语义,不是覆盖。如果你在两条路由上都配了AddRequestHeader并且下游恰好接的是同一个服务,那么下游收到的可能是两个同名的请求头。这算不算 bug 要看场景,但知道这个是追加语义很重要。

4.2 RetryGatewayFilterFactory:重试不是“再调一次”那么简单

Retry的源码远比表面看起来复杂,因为它涉及请求体是否可重复读取、流量是否已经发出、连接是否已建立等一系列状态判断。

核心配置类RetryConfig包含以下字段:

private int retries; // 重试次数 private List<HttpStatus> statuses; // 按状态码触发重试 private List<HttpMethod> methods; // 按请求方法触发重试 private List<HttpStatus.Series> series; // 按状态分类触发重试 private List<Class<? extends Throwable>> exceptions; // 按异常触发重试 private BackoffConfig backoff; // 退避策略

真正执行重试逻辑的过滤器内部,会先判断当前请求是否已经被消费过。我截取核心逻辑的大致结构:

return (exchange, chain) -> { return retry(exchange, chain, config.getRetries(), new ArrayList<>()); }; private Mono<Void> retry(ServerWebExchange exchange, GatewayFilterChain chain, int retries, List<Throwable> exceptions) { return chain.filter(exchange).doOnError(throwable -> { exceptions.add(throwable); if (RETRY_ATTRIBUTE_EXCEPTION_LIST ... ) { // 记录异常 } }).then(); }

重试过程中最微妙的问题就是请求体缓冲:如果请求体已经被下游读取过一次,再次重试时流已经关闭,就没法重新发送了。所以官方文档特别说明:带有请求体的请求,默认情况下Retry不会重试,除非你在配置里设置了基于ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR的缓存逻辑。

另一个需要警惕的陷阱是“重试与幂等的关系”。GET 请求重试基本安全,但 POST、PUT 这类可能产生副作用的请求,一旦下游处理成功但响应在传输中丢失,重试就会导致重复下单、重复扣费这类严重后果。这个过滤器适合用在读多写少且下游具备幂等能力的场景,否则一定三思。

4.3 CircuitBreakerGatewayFilterFactory:把熔断器拉进过滤器链

CircuitBreaker过滤器是另一个典型,它不直接做熔断,而是把 Spring Cloud Circuit Breaker 抽象层上的ReactiveCircuitBreaker集成到网关过滤链路里。

它在apply方法中做了这样几件事:

  1. 根据配置里的name拿到对应的ReactiveCircuitBreaker实例。
  2. 调用circuitBreaker.run(...)包裹下游的chain.filter(exchange),在回调里处理熔断打开时的 fallback 逻辑。
  3. 如果配置了fallbackUri,则通过exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_ALREADY_ROUTED_ATTR, true)标记当前请求已路由,然后发送 forward 请求到 fallback 地址,避免陷入无限转发。

我见过很多人在用这个过滤器时犯同一个错误:只配置了name和fallbackUri,但没有专门为 fallbackUri 再定义一条路由。结果熔断触发后,网关要把请求 forward 到/fallback,却发现根本没有匹配的路由,直接报 404。正确的做法是额外加一条路由专门处理 fallback:

spring: cloud: gateway: routes: - id: user_route uri: lb://user-service predicates: - Path=/user/** filters: - name: CircuitBreaker args: name: userCb fallbackUri: forward:/fallback - id: fallback_route uri: http://fallback-service predicates: - Path=/fallback

另外要记住,CircuitBreaker 并不改变下游请求本身,它只是给下游调用加了一层“保险丝”。熔断状态、半开状态下的探测请求,这些逻辑都在底层各品牌的熔断器实现中,配置时注意选择与实现类匹配的参数,例如基于 Redis 计数还是基于本地滑动窗口。

5. 自定义 GatewayFilter 的两种方式与执行顺序控制

内置过滤器终究覆盖不了所有业务场景。我实际做过一个灰度发布的过滤器,需要根据用户请求头里的某个身份标识动态改写下游请求路径,这种逻辑没有现成的过滤器可用,只能自己写。自定义有两种常见形态,我分别说清楚,你根据自己的需求选。

5.1 直接实现 GatewayFilter 接口

最简单的形态是写一个类实现GatewayFilter和Ordered:

@Component public class CustomHeaderFilter implements GatewayFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest().mutate() .header("X-Custom-Filter", "active") .build(); return chain.filter(exchange.mutate().request(request).build()); } @Override public int getOrder() { return -100; } }

这种形态的过滤器不能直接在 YAML 的filters里用短名配置,因为它没有对应的工厂。使用方式是写进一个RouteLocator的配置类里,手动装配:

@Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder, CustomHeaderFilter customHeaderFilter) { return builder.routes() .route("custom_route", r -> r.path("/custom/**") .filters(f -> f.filter(customHeaderFilter)) .uri("lb://custom-service")) .build(); }

我一直觉得这种方式适合“固定逻辑”的过滤器,因为它的行为完全是写死的。

5.2 继承 AbstractGatewayFilterFactory:让过滤器也支持配置

如果你的过滤器需要像内置过滤器一样,在不同路由上使用不同参数,那就用第二种方式,继承AbstractGatewayFilterFactory<Config>。下面是一个给请求追加固定 Header 的可配置版本:

@Component public class CustomAddHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomAddHeaderGatewayFilterFactory.Config> { public CustomAddHeaderGatewayFilterFactory() { super(Config.class); } @Override public List<String> shortcutFieldOrder() { return Arrays.asList("headerName", "headerValue"); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest().mutate() .header(config.headerName, config.headerValue) .build(); return chain.filter(exchange.mutate().request(request).build()); }; } public static class Config { private String headerName; private String headerValue; // getter / setter 省略 } }

这样在 YAML 里就可以写了:

filters: - CustomAddHeader=X-Trace-Id, abc123

注意:配置里的短名是去掉GatewayFilterFactory后缀的部分。你的类名叫CustomAddHeaderGatewayFilterFactory,配置里就写CustomAddHeader。如果你配置里写全名,也能生效,因为前文说过工厂查找逻辑两种写法都支持。

这两种方式的对比我放在一起说:

对比维度直接实现 GatewayFilter继承 AbstractGatewayFilterFactory
配置驱动不支持,逻辑写死支持,可灵活配置参数
装配方式手动加到 RouteLocator扫描 Bean 后按短名装配
适合场景全网关统一的固定逻辑不同路由不同参数的灵活需求
实现门槛低中,需理解配置绑定

5.3 执行顺序控制:这决定了你改的是请求还是响应

前面提到过Ordered接口,这里展开讲。对于自定义的GatewayFilter,如果不实现Ordered,默认 order 是 0。那么问题来了:如果一条路由上既配置了AddRequestHeader(order 为 0),又配置了你的自定义过滤器(order 也是 0),执行顺序是啥?

排序算法在AnnotationAwareOrderComparator中,当 order 相同时,它会比较对象在容器中的注册顺序,这在本质上是不稳定的。如果你依赖这种不确定性来保证业务逻辑顺序,大概率会在某次应用重启后得到不同的行为。

所以我的建议是:所有自定义GatewayFilter一律显式实现Ordered,并且根据你要做的事选择合适的 order 区间。

  • 需要修改请求:order 设为负数,比如-100,确保在转发之前生效。
  • 需要修改响应:order 设为正数,但要小于NettyRoutingFilter的Integer.MAX_VALUE,否则转发已经完成,你再改响应头就晚了。
  • 需要做日志、监控这类旁路逻辑:order 可以设为 0 附近,不影响主流程,但也别指望它能在所有过滤器的最前面或最后面。

有一种更稳妥的写法:如果你重复设置了相同的 order 且确实需要严格顺序,直接在自定义过滤器内部维护一个“子链”,也就是一个List<GatewayFilter>列表,按明确的次序逐个执行,避免把顺序暴露给全局排序器。这种方式适合业务上强依赖执行次序的场景。

还有一点容易被忽略:Route上的过滤器列表顺序在你配置时是固定的,但经过combineGlobalFiltersAndGatewayFilters合并排序后会重排。如果你在排查问题时看到执行顺序和 YAML 里写的顺序不一致,别惊讶,先去看所有相关过滤器的getOrder()值。

6. 调试过滤器链的实用技巧

最后聊几个我在生产环境排障时会用到的调试方法,这些经验写在博客里就当是给自己留的备忘录。

先在配置里打开网关的 debug 日志:

logging: level: org.springframework.cloud.gateway: debug org.springframework.web.reactive: debug

开启后,请求经过过滤器链时,日志里会输出Route matched: xxx、FilteringWebHandler handled request这类关键信息,可以看到当前请求匹配到了哪个路由、走到了哪一步。

如果你想精确看到过滤器的执行顺序,可以在自定义过滤器里临时加日志,输出当前 exchange 里的路由 ID 和过滤器链的剩余数量,这样能直观看到自己写的过滤器在整条链的前后位置。

还有一种常见排查需求是:请求头到底有没有被正确加上?这个不必看日志,直接在过滤器里把当前exchange.getRequest().getHeaders()打印出来即可。我之前排查过一个问题,两个过滤器的 order 冲突导致请求头被后执行的过滤器覆盖,打一次 header 日志就立刻真相大白。

另一个很实用的场景是模拟线上问题:生产环境把某个下游服务的实例全部摘掉,观察网关的Retry过滤器是否如预期重试、CircuitBreaker是否按配置打开。这种演练建议在压测环境先做,别直接拿生产流量的真实路径试。

想深入看某一个过滤器到底做了什么,最直接的办法还是本地拉一份源码,找到对应的GatewayFilterFactory类,打上断点,然后发起一个触发该过滤器的请求,用 IDE 的调试模式单步走一遍。Spring Cloud Gateway 是响应式框架,断点调用栈比普通 Spring MVC 深很多,但多跟几次就会习惯。这里给个小提示:断点首选打在apply(Config config)方法上,因为所有工厂的入口都在这里,而且能看到配置对象完整绑定之后的值。

扫一眼内置过滤器的源码,你会发现大部分工厂类都遵循同一个套路:定义 Config、声明 shortcutFieldOrder、在 apply 里返回匿名 GatewayFilter。看懂一个就相当于看懂了一整片。这也是我为什么强烈建议你把AddRequestHeader的实现读透,因为它本身就是这个框架里最简单也最典型的工厂范式。后面你再去读Retry、CircuitBreaker那些复杂的工厂,思路会顺畅很多。

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

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

立即咨询