基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Gateway 中的全局过滤器(GlobalFilter)和局部过滤器(GatewayFilter)有什么区别?

知识点图片

在 Spring Cloud Gateway 中,GlobalFilter(全局过滤器)GatewayFilter(局部过滤器/路由过滤器) 是两种用于拦截和处理 HTTP 请求和响应的机制。它们的核心区别主要体现在作用范围、配置方式、实现复杂度以及应用场景上。

以下是它们的详细对比:

1. 作用范围 (Scope)

  • GlobalFilter(全局过滤器): 作用于所有的路由。只要请求经过 Gateway,无论匹配到哪个路由规则,全局过滤器都会执行。
  • GatewayFilter(局部过滤器): 作用于指定的路由。只有当请求匹配到配置了该过滤器的特定路由时,它才会被执行。

2. 配置与生效方式 (Configuration)

  • GlobalFilter:
    • 生效方式: 只需要实现 GlobalFilter 接口,并将其注册为 Spring Bean(例如加上 @Component 注解),Gateway 会自动扫描并将其应用到所有路由中。
    • 特点: 无需在 application.yml 或代码中为特定路由进行绑定。
  • GatewayFilter:
    • 生效方式: 需要通过配置文件(application.yml)或 Java 路由 API(RouteLocatorBuilder显式地绑定到某个具体的路由上。
    • 特点: 如果不在路由规则中配置,它就不会生效。

3. 实现方式 (Implementation)

  • GlobalFilter 的实现: 直接实现 GlobalFilterOrdered 接口即可。代码非常直接。
    java
    @Component
    public class MyGlobalFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 全局逻辑,如鉴权
            return chain.filter(exchange);
        }
        @Override
        public int getOrder() { return 0; }
    }
  • GatewayFilter 的实现: 通常不直接实现 GatewayFilter,而是需要实现一个工厂类(继承 AbstractGatewayFilterFactory)。这是因为局部过滤器通常需要接收 YAML 中配置的参数。
    java
    @Component
    public class MyCustomGatewayFilterFactory extends AbstractGatewayFilterFactory<MyCustomGatewayFilterFactory.Config> {
        public MyCustomGatewayFilterFactory() { super(Config.class); }
    
        @Override
        public GatewayFilter apply(Config config) {
            return (exchange, chain) -> {
                // 局部逻辑,如添加特定请求头
                return chain.filter(exchange);
            };
        }
        public static class Config { /* 接收 YAML 配置的属性 */ }
    }
    (配置 YAML 时需写:filters: - MyCustom=配置值)

4. 典型应用场景 (Use Cases)

  • GlobalFilter: 处理跨越所有业务的通用关注点
    • 全局统一的 Token 鉴权 / 登录校验。
    • 全局请求日志记录。
    • 全局 IP 黑白名单过滤。
    • 底层的全局逻辑(如 Gateway 自带的 LoadBalancerClientFilter 用于全局负载均衡,NettyRoutingFilter 用于全局路由转发)。
  • GatewayFilter: 处理针对特定 API 或微服务的个性化需求
    • 路径重写/裁剪: 例如 StripPrefix(去掉前缀)、RewritePath
    • 参数修改: 例如给发往特定微服务的请求添加指定的 Header (AddRequestHeader) 或 Parameter。
    • 特定限流: 只对某个高并发的特定接口/路由进行 RequestRateLimiter 限流。
    • 熔断降级: 针对特定的脆弱服务配置 Hystrix/Resilience4j 熔断。

5. 执行顺序 (Execution Order)

当一个请求匹配到一个路由时,Spring Cloud Gateway 会将该路由配置的 GatewayFilter所有的 GlobalFilter 提取出来,合并成一个完整的过滤器链 (Filter Chain)。

  • 合并后,Gateway 会利用一个适配器(GatewayFilterAdapter)将 GlobalFilter 包装成 GatewayFilter。
  • 合并后的过滤器链会统一根据 @Order 注解或 Ordered 接口返回的值进行升序排序(数字越小,优先级越高,越先执行)。
  • 注意: 如果一个 GlobalFilter 和一个 GatewayFilter 的 order 值刚好相同,Spring Cloud Gateway 的默认逻辑是:默认过滤器 (Default Filters) > 局部过滤器 (GatewayFilter) > 全局过滤器 (GlobalFilter) (具体行为可能随版本微调,建议开发时通过明确指定不同的 order 值来避免冲突)。

总结对比表

特性 GlobalFilter (全局过滤器) GatewayFilter (局部过滤器)
作用范围 所有路由 (All Routes) 指定绑定的具体路由 (Specific Routes)
使用方式 注册为 Spring Bean (@Component) 在 YAML 或 Java 路由代码中显式配置
实现接口 GlobalFilter 通常实现 GatewayFilterFactory
传参支持 不直接支持通过 YAML 传参 强依赖工厂模式,非常方便通过 YAML 传参
内置代表 ForwardRoutingFilter, LoadBalancer... StripPrefix, AddRequestHeader...
适用场景 全局鉴权、全局日志、全局黑白名单 路径重写、局部服务限流、特定 Header 修改
粒度 粗粒度(全局统一) 细粒度(精确到单个路由)

开发建议:
如果你想写的逻辑是“只要请求进来我就要拦截处理的”,请写 GlobalFilter;如果你想写的逻辑是“只有请求某个特定微服务时才需要特殊处理的”,请写 GatewayFilterFactory

00:00
00:00