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 的实现: 直接实现
GlobalFilter和Ordered接口即可。代码非常直接。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 中配置的参数。(配置 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 配置的属性 */ } }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。
右滑查看面试常问