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 最强大的特性之一,可以封装复杂的业务逻辑(如签名、加密、限流),让配置层保持简洁。

相关推荐
笨蛋不要掉眼泪2 小时前
Spring Cloud Gateway 扩展:全局跨域配置
java·分布式·微服务·架构·gateway
BugShare2 小时前
路由器配置 DDNS 实现稳定的远程访问
网络·智能路由器
java1234_小锋2 小时前
Java高频面试题:说说Redis的内存淘汰策略?
java·开发语言·redis
迪巴拉15252 小时前
抗社交网络压缩的鲁棒对抗扰动生成研究
网络·人工智能·php
chentao1062 小时前
Spring应用事件机制实践
后端
序安InToo2 小时前
第4课|程序结构与编译流程
后端·操作系统·嵌入式
Hx_Ma162 小时前
播放器逻辑
java·开发语言
名字还在想2 小时前
SpringBoot 自动装配-自定义Stater
后端
柳鲲鹏2 小时前
LINUX下载编译libosmscout
linux·运维·服务器