在 Spring Cloud Gateway 中,过滤器(Filter) 是核心组件之一,其设计深度依赖于责任链模式。通过责任链,Gateway 能够将多个过滤器按特定顺序串联起来,对请求和响应进行逐层处理,实现路由转发、鉴权、日志记录、限流等功能。
一、责任链模式在 Spring Gateway 中的核心体现
Spring Gateway 的过滤器责任链遵循以下逻辑:
- 链的组成:由多个
GatewayFilter实例组成,每个过滤器负责特定的处理逻辑(如修改请求头、校验 token、记录日志等)。 - 执行顺序:过滤器按预设顺序依次执行,每个过滤器处理完成后,将请求传递给下一个过滤器,直到完成全部处理并转发到目标服务,或在中途被拦截(如鉴权失败)。
- 双向处理:责任链分为**“前置处理”(请求发送到目标服务前)和“后置处理”**(目标服务返回响应后),类似 Servlet 中的
FilterChain,但更灵活。
二、核心组件与责任链实现
1. GatewayFilter:责任链的节点
GatewayFilter 是过滤器的核心接口,定义了处理请求的方法。其默认实现类 GatewayFilterAdapter 中,核心方法为:
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
ServerWebExchange:封装了 HTTP 请求(ServerHttpRequest)和响应(ServerHttpResponse)的上下文对象。GatewayFilterChain:代表过滤器链,用于将请求传递给下一个过滤器。
2. GatewayFilterChain:责任链的管理器
GatewayFilterChain 是责任链的核心接口,定义了如何将请求传递给下一个过滤器:
public interface GatewayFilterChain {
Mono<Void> filter(ServerWebExchange exchange);
}
其默认实现类 DefaultGatewayFilterChain 维护了一个过滤器列表和当前执行索引,核心逻辑如下:
- 保存所有待执行的
GatewayFilter集合。 - 记录当前执行到的过滤器索引(
index)。 - 执行当前过滤器后,通过
index+1获取下一个过滤器,形成链式调用。
3. 责任链的构建与执行流程
Spring Gateway 会为每个路由(Route)构建独立的责任链,流程如下:
- 收集过滤器:当请求匹配到某个路由时,Gateway 会收集该路由关联的所有过滤器(包括全局过滤器
GlobalFilter和路由专属过滤器GatewayFilter)。 - 排序过滤器:通过
org.springframework.core.Ordered接口的getOrder()方法对过滤器排序,确保执行顺序可控(值越小,优先级越高)。 - 构建责任链:将排序后的过滤器封装为
DefaultGatewayFilterChain,形成责任链。 - 执行责任链:从第一个过滤器开始执行,依次传递请求,直到所有过滤器完成处理,最终转发到目标服务。
三、过滤器执行的双向流程(重点)
Spring Gateway 的过滤器责任链是双向的,每个过滤器可以在“请求转发前”和“响应返回后”两个阶段处理逻辑,类似 AOP 的“环绕通知”。
执行流程示意图:
客户端请求 → [过滤器1 前置处理] → [过滤器2 前置处理] → ... → 转发到目标服务
↓
客户端响应 ← [过滤器1 后置处理] ← [过滤器2 后置处理] ← ... ← 目标服务返回响应
代码示例(自定义过滤器):
@Component
public class CustomFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 前置处理:请求转发到服务前执行(如打印日志、鉴权)
System.out.println("前置处理:" + exchange.getRequest().getPath());
// 2. 调用 chain.filter() 传递请求给下一个过滤器
// 这是一个异步操作,返回的 Mono<Void> 会在后续流程(包括目标服务响应)完成后触发
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> {
// 3. 后置处理:服务返回响应后执行(如修改响应头、记录响应时间)
System.out.println("后置处理:" + exchange.getResponse().getStatusCode());
}));
}
@Override
public int getOrder() {
// 排序:值越小,越先执行
return 0;
}
}
- 前置处理:
chain.filter(exchange)之前的逻辑,用于处理请求(如校验 token、添加请求头)。 - 后置处理:
chain.filter(exchange).then(...)中的逻辑,用于处理响应(如记录响应时间、修改响应内容)。 - 若前置处理中直接返回
Mono.error(...),则会中断责任链,不再向后传递(如鉴权失败时直接返回 401)。
四、全局过滤器与路由过滤器的融合
Spring Gateway 有两种过滤器:
- GlobalFilter:全局生效,对所有路由有效(如日志、限流过滤器)。
- GatewayFilter:仅对特定路由生效(如路由专属的重试过滤器)。
责任链构建时,会将这两种过滤器合并排序,统一纳入 DefaultGatewayFilterChain 执行。排序规则通过 getOrder() 实现,例如:
- 内置的
Ordered.HIGHEST_PRECEDENCE(最高优先级)用于早期处理(如负载均衡)。 - 内置的
Ordered.LOWEST_PRECEDENCE(最低优先级)用于后期处理(如响应日志)。
五、责任链模式的优势
- 解耦:请求发送者(客户端)与处理者(过滤器)分离,无需关心具体处理逻辑和顺序。
- 灵活性:新增或移除过滤器无需修改现有代码,只需实现
GlobalFilter或配置路由过滤器即可。 - 可扩展性:通过排序机制,可精确控制过滤器执行顺序,满足复杂业务需求(如先鉴权后限流)。
- 双向处理:支持请求和响应的全链路干预,适合网关的流量管控场景。
六、总结
Spring Gateway 通过 GatewayFilter 和 GatewayFilterChain 实现了责任链模式,核心特点是:
- 过滤器按顺序组成责任链,依次处理请求和响应。
- 支持前置/后置双向处理,灵活干预请求生命周期。
- 全局过滤器与路由过滤器统一排序,共同参与责任链执行。
这种设计让 Gateway 能够轻松扩展各种功能(如鉴权、限流、日志),同时保持代码的清晰和解耦,是网关架构的核心设计思想之一。
注意:本文归作者所有,未经作者允许,不得转载