Spring Cloud 过滤器工厂
Spring Cloud Gateway
中的过滤器工厂(GatewayFilterFactory
),是用来**生成特定逻辑的过滤器(GatewayFilter
)**的工厂类。其本质上是路由级别的过滤器,通常在每个路由中显式配置,用于实现针对性的请求处理逻辑。
1. 主要接口
GatewayFilter
: 定义了过滤器的基本行为 (filter
方法)。AbstractGatewayFilterFactory<C>
: 最常用的基类,通常继承这个类来创建自定义过滤器工厂,泛型C
代表该过滤器所需的配置类。
Spring Cloud Gateway
提供了很多内置的过滤器工厂,并允许我们通过实现过滤器工厂接口,来创建自定义的过滤器工厂,以满足更复杂的业务需求。
1. 过滤器的生命周期
Pre Filter
(前置过滤器):在请求路由到实际的服务之前处理请求。Post Filter
(后置过滤器):在请求已经路由到服务并且响应已经返回之后处理响应。Error Filter
(错误过滤器):处理在过滤器链中的任何错误。
2. 过滤器工厂工作原理
在路由配置中通过 filters
属性指定过滤器工厂及其参数,网关启动或路由刷新时,系统会根据配置实例化对应的 GatewayFilter
。当请求匹配某个路由后,该路由的所有 GatewayFilter
会与全局过滤器(GlobalFilter
)一起组成一个过滤器链。请求在这条链中依次通过每个过滤器,期间可以执行请求头或路径修改、认证校验、限流、重试、日志记录等操作,也可以中断或放行请求。整个过程基于责任链模式,确保请求在进入后端服务前得到灵活控制与增强。
GlobalFilter
是可选的全局增强机制,不是过滤器链必须的一环;没有它,Gateway
同样可以根据路由过滤器正常转发和处理请求。
3. 自定义工厂实例
- 配置示例(
YAML
)
spring:cloud:gateway:routes:- id: my_routeuri: https://downstream-servicepredicates:- Path=/api/**filters:- AddRequestHeader=X-Request-Foo, Bar # 添加请求头 X-Request-Foo: Bar- RewritePath=/api/(?<segment>.*), /${segment} # 路径重写:/api/xxx → /xxx- CircuitBreaker=myCircuitBreaker # 使用名为 myCircuitBreaker 的熔断器配置- RequestRateLimiter=#{@myRateLimiter} # 使用名为 myRateLimiter 的限流器 Bean(SpEL 语法)- MyCustom=value1,value2 # 使用自定义过滤器工厂,参数由 shortcutFieldOrder 定义
- 定义配置类
MyFilterConfig
public class MyFilterConfig {private String param1;private String param2;// Getter & Setterpublic String getParam1() { return param1; }public void setParam1(String param1) { this.param1 = param1; }public String getParam2() { return param2; }public void setParam2(String param2) { this.param2 = param2; }
}
- 实现
MyCustomGatewayFilterFactory
@Component
public class MyCustomGatewayFilterFactory extends AbstractGatewayFilterFactory<MyFilterConfig> {public MyCustomGatewayFilterFactory() {super(MyFilterConfig.class);}@Overridepublic GatewayFilter apply(MyFilterConfig config) {return (exchange, chain) -> {// 修改请求头,添加自定义值ServerHttpRequest request = exchange.getRequest().mutate().header("X-Custom-Header", config.getParam1()).build();// 替换请求(必须)ServerWebExchange modifiedExchange = exchange.mutate().request(request).build();// 执行过滤器链return chain.filter(modifiedExchange).then(Mono.fromRunnable(() -> {// 响应阶段可选处理System.out.println("MyCustomFilter executed. Param2 = " + config.getParam2());}));};}// 指定 YAML 中参数的顺序(用于简洁配置)@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("param1", "param2");}
}
filters:- MyCustom=abc, xyz # 自动绑定 param1=abc, param2=xyz
默认规则是:类名去掉 GatewayFilterFactory
后缀 → 过滤器名称(如上面的 MyCustomGatewayFilterFactory
→ MyCustom
)
4. 内置过滤器工厂
Spring Cloud Gateway
提供了一些 内置过滤器工厂,它们封装了常见的请求处理逻辑,可以直接在路由配置中使
名称 | 说明 | 示例 |
---|---|---|
AddRequestHeader | 向请求添加头部信息 | filters: - AddRequestHeader=X-Request-Foo, Bar |
AddResponseHeader | 向响应添加头部信息 | filters: - AddResponseHeader=X-Response-Foo, Bar |
SetPath | 重写请求的路径 | filters: - SetPath=/newpath/{segment} |
RewritePath | 重写请求路径,根据正则规则替换路径 | filters: - RewritePath=/oldpath/(?<segment>.*), /newpath/${segment} |
RequestRateLimiter | 限制请求的速率(基于令牌桶) | filters: - RequestRateLimiter=redisRateLimiter=1,2 |
StripPrefix | 移除请求路径中的前缀 | filters: - StripPrefix=1 |
Retry | 请求失败时自动重试 | filters: - Retry=3,5000 |
RemoveRequestHeader | 从请求中移除指定的请求头 | filters: - RemoveRequestHeader=X-Request-Foo |
RemoveResponseHeader | 从响应中移除指定的响应头 | filters: - RemoveResponseHeader=X-Response-Foo |
4.1. AddRequestHeader
- 功能:为请求添加一个或多个 HTTP 请求头。
- 常用场景:在请求中增加认证信息,或为后端服务添加自定义标头。
filters:- AddRequestHeader=X-Request-Foo, Bar
此配置会将
X-Request-Foo: Bar
添加到每个请求的请求头中。
4.2. AddResponseHeader
- 功能:为响应添加 HTTP 响应头。
- 常用场景:修改返回的响应头,例如增加
CORS
头部,或设置缓存控制头。
filters:- AddResponseHeader=X-Response-Foo, Bar
此配置会在响应头中加入
X-Response-Foo: Bar
。
4.3. SetPath
- 功能:重写请求的路径。
- 常用场景:例如,将请求路由到不同的路径,但保持其他信息不变。
filters:- SetPath=/newpath/{segment}
此配置会将请求路径重写为
/newpath/{segment}
,即将请求路径/oldpath/xxx
改为/newpath/xxx
。
4.4. RewritePath
- 功能:基于正则表达式重写请求路径。
- 常用场景:如果想根据特定规则重写路径中的一部分。
filters:- RewritePath=/oldpath/(?<segment>.*), /newpath/${segment}
此配置会将请求路径
/oldpath/abc
重写为/newpath/abc
。这里的正则表达式用于捕获路径的一部分,并替换成新的路径。
4.5. RequestRateLimiter
- 功能:限制请求的速率,基于令牌桶算法。适用于限流场景。
- 常用场景:控制客户端请求频率,防止流量过大对后端服务造成压力。
filters: - RequestRateLimiter=redisRateLimiter=1,2
此配置通过 Redis 限制每秒最大 1 次请求,并且最多允许 2 个并发请求。
4.6. StripPrefix
- 功能:移除请求路径中的前缀。
- 常用场景:如果路由到后端服务时,需要去掉 URL 路径中的某些前缀部分。
filters: - StripPrefix=1
此配置会将请求路径中的前缀部分移除。比如,路径
/foo/bar
会被转发到/bar
。
4.7. Retry
- 功能:请求失败时重试,常用于临时不可用的后端服务。
- 常用场景:自动重试失败的请求。
filters: - Retry=3,5000
此配置会对失败的请求进行最多 3 次重试,每次重试之间的间隔为 5000 毫秒(5秒)。
5. 内置过滤器示例
以AddRequestHeader
为例,给所有进入ms-web-service
的请求添加一个请求头:Header=Camellia·XIAOHUA
,只需要修改GateWay
服务的application.yml
文件,添加路由过滤即可。
spring:cloud:gateway:routes: # 网关路由配置,用于定义各种路由规则- id: ms-web-service # 路由ID,自定义的唯一标识符uri: lb://ms-web-service predicates: - Path=/web/** filters:- AddRequestHeader=Header, Camellia·XIAOHUA # 请求过滤器,添加一个请求头
当前过滤器写在ms-web-service
路由下,因此仅对访问该服务的请求有效。如果要对所有路由都生效,则需要将过滤器工厂写到==default
==下。
spring:cloud:gateway:routes: # 网关路由配置,用于定义各种路由规则- id: ms-web-service # 路由ID,自定义的唯一标识符uri: lb://ms-web-service predicates: - Path=/web/** filters:- AddRequestHeader=Header, Camellia·XIAOHUA # 请求过滤器,添加一个请求头default-filters: # 默认过滤项,应用于所有路由- AddRequestHeader=Header, Global filters! # 请求过滤器,添加一个全局请求头