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

相关推荐
冉冰学姐20 小时前
基于ssm的技能比赛报名管理系统29817vn0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
java·数据库·spring·ssm 框架应用
代码雕刻家1 天前
3.5.Maven-依赖管理-依赖配置&依赖传递
java·maven
!chen1 天前
MyBatis-plus拓展之字段类型处理器、自动填充和乐观锁
java·tomcat·mybatis
无限大61 天前
《AI观,观AI》:善用AI赋能|让AI成为你深耕核心、推进重心的“最强助手”
前端·后端
uzong1 天前
CoPaw是什么?-- 2026年开源的国产个人AI助手
人工智能·后端
Jin、yz1 天前
JAVA 八股
java·开发语言
无心水1 天前
【任务调度:框架】11、分布式任务调度进阶:高可用、幂等性、性能优化三板斧
人工智能·分布式·后端·性能优化·架构·2025博客之星·分布式调度框架
va学弟1 天前
Java 网络通信编程(6):视频通话
java·服务器·网络·音视频
pjw198809031 天前
Spring Framework 中文官方文档
java·后端·spring
盒马盒马1 天前
Rust:迭代器
开发语言·后端·rust