**摘要:** 本文将带你深入 Spring Cloud Gateway 的核心组件------过滤器(Filter)。我们将从基础配置讲起,涵盖默认过滤器(Default Filters)、全局过滤器(Global Filters)以及如何自定义一个强大的过滤器工厂(Custom Filter Factory)。通过图文结合与代码实战,助你彻底掌握 Gateway 的流量处理能力。
1. 过滤器(Filter)是什么?
在 Spring Cloud Gateway 中,过滤器是处理请求和响应的核心组件。它们在请求到达目标服务之前(Pre)或响应返回客户端之前(Post)执行逻辑,用于修改请求头、响应头、重写路径、限流、鉴权等操作。
请求经过一系列过滤器链(Filter Chain)后到达目的地,响应再逆向经过过滤器链返回:

2. 基础配置:路由过滤器(Route Filters)
这是最常用的过滤器,绑定在具体的路由规则上。
2.1 内置过滤器示例
在配置中,使用了 RewritePath过滤器来重写请求路径:
routes:
- id: product-route
uri: lb://service-product
predicates:
- Path=/api/product/**
filters:
# 将 /api/product/xxx 重写为 /xxx
- RewritePath=/api/product/(?<segment>.*),/$\{segment}
2.2 默认过滤器(Default Filters)
默认过滤器会应用到所有路由上,无需在每个路由中重复配置。
spring:
cloud:
gateway:
default-filters:
# 为所有响应添加 X-Response 头
- AddResponseHeader=X-Response, 123
3. 全局过滤器(Global Filters)
全局过滤器作用于所有路由,通常用于日志记录、统一鉴权等跨切面逻辑。
3.1 实战:请求耗时监控
RtGlobalFilter是一个典型的全局过滤器,用于记录请求的开始和结束时间:
java
@Component
@Slf4j
public class RtGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().toString();
log.info("进入全局过滤器: {} 开始时间: {}", path, System.currentTimeMillis());
// doFinally 会在请求处理完成后执行,无论成功或失败
return chain.filter(exchange).doFinally(result -> {
log.info("全局过滤器结束: {} 结束时间: {}", path, System.currentTimeMillis());
});
}
@Override
public int getOrder() {
return 0; // 优先级,数值越小优先级越高
}
}
4. 高阶玩法:自定义过滤器工厂(Custom Filter Factory)
当内置过滤器无法满足需求时,我们可以自定义过滤器。 OnceTokenGatewayFilterFactory是一个非常实用的例子,它允许动态生成 UUID 或 JWT。
4.1 核心代码解析
这个工厂继承自 AbstractNameValueGatewayFilterFactory,这意味着它接受"名称"和"值"两个参数。
java
@Component
public class OnceTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> {
// 注意:这里是 chain.filter(exchange).then(...)
// 表示先放行请求,等响应回来后再执行后续逻辑(Post Filter)
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
String value = config.getValue();
// 动态逻辑:如果值是 uuid,则生成 UUID
if ("uuid".equalsIgnoreCase(value)) {
value = UUID.randomUUID().toString();
}
// 动态逻辑:如果值是 jwt,则返回预设的 JWT
if ("jwt".equalsIgnoreCase(value)) {
value = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
}
// 添加响应头
headers.add(config.getName(), value);
}));
};
}
}
4.2 配置使用
在 YAML 中配置该自定义过滤器:
routes:
- id: product-route
uri: lb://service-product
filters:
- RewritePath=/api/product/(?<segment>.*),/$\{segment}
# 使用自定义过滤器,添加 X-Response-Token 头,值为 uuid
- OnceToken=X-Response-Token,uuid
5. 总结与建议
-
Pre vs Post: 注意
chain.filter(exchange)的位置。如果逻辑写在then之前,是 Pre Filter(前置);写在then之后,是 Post Filter(后置)。OnceToken是典型的后置过滤器,用于修改响应。 -
Order 优先级: 全局过滤器的
getOrder()方法决定了执行顺序,合理设置可以避免逻辑冲突。 -
**扩展性:** 自定义过滤器工厂是 Gateway 最强大的特性之一,可以封装复杂的业务逻辑(如签名、加密、限流),让配置层保持简洁。