Spring Cloud Gateway 核心篇:深入解析过滤器(Filter)机制与实战

**摘要:**​ 本文将带你深入 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. 总结与建议

  1. Pre vs Post: ​ 注意 chain.filter(exchange)的位置。如果逻辑写在 then之前,是 Pre Filter(前置);写在 then之后,是 Post Filter(后置)。 OnceToken是典型的后置过滤器,用于修改响应。

  2. Order 优先级: ​ 全局过滤器的 getOrder()方法决定了执行顺序,合理设置可以避免逻辑冲突。

  3. **扩展性:**​ 自定义过滤器工厂是 Gateway 最强大的特性之一,可以封装复杂的业务逻辑(如签名、加密、限流),让配置层保持简洁。

相关推荐
砍材农夫3 小时前
spring-ai 第四多模态API
java·人工智能·spring
她说..6 小时前
Java 对象相关高频面试题
java·开发语言·spring·java-ee
Boop_wu6 小时前
[Java 算法] 字符串
linux·运维·服务器·数据结构·算法·leetcode
庞轩px6 小时前
深入理解 sleep() 与 wait():从基础到监视器队列
java·开发语言·线程··wait·sleep·监视器
m0_694845577 小时前
Dify部署教程:从AI原型到生产系统的一站式方案
服务器·人工智能·python·数据分析·开源
小码哥_常7 小时前
Spring Boot 中JWT登录授权+无感刷新,看这篇就够了!
后端
皮皮林5517 小时前
面试官:ZSet 的底层实现是什么?
java
码云数智-大飞8 小时前
C++ RAII机制:资源管理的“自动化”哲学
java·服务器·php
2601_949816588 小时前
Spring+Quartz实现定时任务的配置方法
java
白毛大侠8 小时前
理解 Go 接口:eface 与 iface 的区别及动态性解析
开发语言·网络·golang