摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/filter-intro/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Spring-Cloud-Gateway 2.0.X M4
阅读源码最好的方式,是使用 IDEA 进行调试 Spring Cloud Gateway 源码,不然会一脸懵逼。
1. 概述
本文主要对 过滤器 GatewayFilter 做整体的认识。
过滤器整体类图如下 :

是不是有点疑惑 GlobalFilter 与 GatewayFilter 的关系 ?且见本文分晓。
推荐 Spring Cloud 书籍:
请支持正版。下载盗版,等于主动编写低级 BUG 。
程序猿DD —— 《Spring Cloud微服务实战》
两书齐买,京东包邮。
2. GatewyFilter
org.springframework.cloud.gateway.filter.GatewayFilter ,网关过滤器接口,代码如下 :
public interface GatewayFilter {
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link GatewayFilterChain}.
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}从接口方法可以看到,和
javax.servlet.Filter类似。
GatewayFilter 有三种类型的子类实现,我们下面每节介绍一种。
2.1 GatewayFilterFactory 内部类
在每个 GatewayFilterFactory 实现类的 #apply(Tuple) 方法里,都声明了一个实现 GatewayFilter 的内部类,以 AddRequestHeaderGatewayFilterFactory 的代码举例子 :
public class AddRequestHeaderGatewayFilterFactory implements GatewayFilterFactory {
@Override
public List<String> argNames() {
return Arrays.asList(NAME_KEY, VALUE_KEY);
}
@Override
public GatewayFilter apply(Tuple args) {
String name = args.getString(NAME_KEY);
String value = args.getString(VALUE_KEY);
return (exchange, chain) -> { // GatewayFilter
ServerHttpRequest request = exchange.getRequest().mutate()
.header(name, value)
.build();
return chain.filter(exchange.mutate().request(request).build());
};
}
}第 13 至 19 行 :定义了一个 GatewayFilter 内部实现类。
在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.2) 之 GatewayFilterFactory 过滤器工厂》 ,我们会详细解析每个 GatewayFilterFactory 定义的GatewayFilter 内部实现类。
2.2 OrderedGatewayFilter
org.springframework.cloud.gateway.filter.OrderedGatewayFilter ,有序的网关过滤器实现类。在 FilterChain 里,过滤器数组首先会按照 order 升序排序,按照顺序过滤请求。代码如下 :
public class OrderedGatewayFilter implements GatewayFilter, Ordered {
private final GatewayFilter delegate;
private final int order;
public OrderedGatewayFilter(GatewayFilter delegate, int order) {
this.delegate = delegate;
this.order = order;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
@Override
public int getOrder() {
return this.order;
}
}delegate属性,委托的 GatewayFilter 。order属性,顺序。#filter(ServerWebExchange, GatewayFilterChain)方法,使用delegate过滤请求。
2.3 GatewayFilterAdapter
org.springframework.cloud.gateway.handler.FilteringWebHandler.GatewayFilterAdapter ,网关过滤器适配器。在 GatewayFilterChain 使用 GatewayFilter 过滤请求,所以通过 GatewayFilterAdapter 将 GlobalFilter 适配成 GatewayFilter 。GatewayFilterAdapter 代码如下 :
private static class GatewayFilterAdapter implements GatewayFilter {
private final GlobalFilter delegate;
public GatewayFilterAdapter(GlobalFilter delegate) {
this.delegate = delegate;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
}delegate属性,委托的 GlobalFilter 。#filter(ServerWebExchange, GatewayFilterChain)方法,使用delegate过滤请求。
在 FilteringWebHandler 初始化时,将 GlobalFilter 委托成 GatewayFilterAdapter ,代码如下 :
public class FilteringWebHandler implements WebHandler {
/**
* 全局过滤器
*/
private final List<GatewayFilter> globalFilters;
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this.globalFilters = loadFilters(globalFilters);
}
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return filters.stream()
.map(filter -> {
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
return new OrderedGatewayFilter(gatewayFilter, order);
}
return gatewayFilter;
}).collect(Collectors.toList());
}
}第 16 至 19 行 :当 GlobalFilter 子类实现了
org.springframework.core.Ordered接口,在委托一层 OrderedGatewayFilter 。这样AnnotationAwareOrderComparator#sort(List)方法好排序。第 20 行 :当 GlobalFilter 子类没有实现了
org.springframework.core.Ordered接口,在AnnotationAwareOrderComparator#sort(List)排序时,顺序值为Integer.MAX_VALUE。目前 GlobalFilter 都实现了
org.springframework.core.Ordered接口。
3. GlobalFilter
org.springframework.cloud.gateway.filter.GlobalFilter ,全局过滤器接口,代码如下 :
public interface GlobalFilter {
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link GatewayFilterChain}.
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}GlobalFilter 和 GatewayFilter 的
#filter(ServerWebExchange, GatewayFilterChain)方法签名一致。官方说,未来的版本将作出一些调整。FROM 《Spring Cloud Gateway》
This interface and usage are subject to change in future milestonesGlobalFilter 会作用到所有的 Route 上。
GlobalFilter 实现类如下类图 :

RoutingFilter
NettyRoutingFilter
WebClientHttpRoutingFilter
WebsocketRoutingFilter
ForwardRoutingFilter
成对的 Filter
NettyRoutingFilter / NettyRoutingFilter
WebClientHttpRoutingFilter / WebClientWriteResponseFilter
梳理 GlobalFilter 的顺序如下 :
TODO 【3030】
4. GatewayFilterChain
org.springframework.cloud.gateway.filter.GatewayFilterChain ,网关过滤器链接口。代码如下 :
public interface GatewayFilterChain {
/**
* Delegate to the next {@code WebFilter} in the chain.
* @param exchange the current server exchange
* @return {@code Mono<Void>} to indicate when request handling is complete
*/
Mono<Void> filter(ServerWebExchange exchange);
}从接口方法可以看到,和
javax.servlet.FilterChain类似。
org.springframework.cloud.gateway.handler.FilteringWebHandler.GatewayFilterAdapter ,网关过滤器链默认实现类。代码如下 :
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private int index;
private final List<GatewayFilter> filters;
public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index++);
return filter.filter(exchange, this);
} else {
return Mono.empty(); // complete
}
}
}