Spring Cloud Gateway 源码精读
概述
Spring Cloud Gateway 基于 Spring WebFlux 构建,核心是 路由匹配 → 过滤器链执行 → 转发 的流程。理解源码有助于排查网关问题、自定义扩展和性能调优。
核心执行流程
请求进入
↓
DispatcherHandler.handle() ← WebFlux 入口
↓
RoutePredicateHandlerMapping.getHandlerInternal()
↓ 解析路由匹配
Route → GatewayFilter[] + URI
↓
FilteringWebHandler.handle()
↓ 执行过滤器链
GlobalFilter + GatewayFilter 组合链
↓
NettyRoutingFilter / ForwardRoutingFilter
↓ 转发到下游
下游服务响应
↓
过滤器链反向执行(响应处理)一、RoutePredicateHandlerMapping
1.1 路由匹配
java
// org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping
public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
@Override
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
// 更新路由属性(兼容性处理)
exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getSimpleName());
// 1. 查找匹配的路由
return lookupRoute(exchange)
.flatMap((Function<Route, Mono<?>>) route -> {
// 2. 匹配成功,设置路由属性
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, route);
// 3. 构建过滤器链
List<GatewayFilter> gatewayFilters = route.getFilters();
// 4. 合并全局过滤器
List<GatewayFilter> combined = combining(
gatewayFilters, // 路由级过滤器
globalFilters // 全局过滤器
);
// 5. 创建 FilteringWebHandler
GatewayFilterChain chain = new SimpleGatewayFilterChain(combined);
// 6. 返回 FilteringWebHandler 作为 Handler
return Mono.just(new FilteringWebHandler(chain));
})
.switchIfEmpty(Mono.empty());
}
}1.2 路由查找过程
java
private Mono<Route> lookupRoute(ServerWebExchange exchange) {
// 遍历 RouteLocator 中的所有路由
return this.routeLocator.getRoutes()
.filter(route -> {
// 逐一匹配 Predicate
return route.getPredicate().test(exchange);
})
.next() // 获取第一个匹配的路由
.flatMap(route -> {
// 增加匹配计数器(用于监控)
exchange.getAttributes().put(
GATEWAY_PREDICATE_MATCHED_ATTR, true);
return Mono.just(route);
});
}二、FilteringWebHandler
2.1 过滤器链执行
java
// org.springframework.cloud.gateway.handler.FilteringWebHandler
public class FilteringWebHandler implements WebHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
// 从 exchange 属性中获取之前构建的过滤器链
GatewayFilterChain chain = exchange.getAttribute(
GATEWAY_FILTER_CHAIN_ATTR);
if (chain == null) {
// 如果路由匹配阶段已构建链则使用,否则重新构建
chain = createChain(exchange);
}
return chain.filter(exchange);
}
private GatewayFilterChain createChain(ServerWebExchange exchange) {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
List<GatewayFilter> filters = route.getFilters();
// 合并全局过滤器(排序)
List<GatewayFilter> combined = combine(
filters,
this.globalFilters
);
// 创建过滤器链
return new DefaultGatewayFilterChain(combined);
}
}2.2 过滤器链执行机制
java
// 简化版:过滤器链的递归执行
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private final List<GatewayFilter> filters;
private final int index;
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
if (this.index < filters.size()) {
// 获取下一个过滤器
GatewayFilter filter = filters.get(this.index);
// 递归调用下一个过滤器
DefaultGatewayFilterChain chain =
new DefaultGatewayFilterChain(this, this.index + 1);
// 执行当前过滤器的 filter 方法
return filter.filter(exchange, chain);
}
// 所有过滤器执行完毕,返回空
return Mono.empty();
}
}2.3 过滤器排序
java
// 合并路由级和全局过滤器时的排序逻辑
private List<GatewayFilter> combine(List<GatewayFilter> routeFilters,
List<GlobalFilter> globalFilters) {
List<GatewayFilter> combined = new ArrayList<>(routeFilters);
// 将 GlobalFilter 包装为 GatewayFilter 后加入
for (GlobalFilter globalFilter : globalFilters) {
combined.add(new GatewayFilterAdapter(globalFilter));
}
// 按 Order 排序
AnnotationAwareOrderComparator.sort(combined);
return combined;
}三、ServerWebExchange 上下文
3.1 核心属性
java
// 请求和响应的持有者
public interface ServerWebExchange {
// 请求
ServerHttpRequest getRequest();
// 响应
ServerHttpResponse getResponse();
// 请求属性(在整个请求生命周期中共享)
Map<String, Object> getAttributes();
// Session
Mono<WebSession> getSession();
// 请求上下文(Spring Security 等使用)
<T> T getRequiredAttribute(String name);
}3.2 属性传递
java
// 过滤器间通过 exchange 属性传递数据
@Component
public class AttributePassingFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 前置过滤器中写入属性
exchange.getAttributes().put("start_time", System.currentTimeMillis());
return chain.filter(exchange)
.doFinally(signalType -> {
// 后置过滤器中读取属性
Long startTime = exchange.getAttribute("start_time");
if (startTime != null) {
long duration = System.currentTimeMillis() - startTime;
System.out.println("Request took " + duration + "ms");
}
});
}
}3.3 请求/响应包装
java
// 装饰器模式:修改请求或响应而不改变原始对象
// 修改请求头
ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
.header("X-Custom-Header", "value")
.build();
exchange = exchange.mutate().request(modifiedRequest).build();
// 包装响应(用于修改响应体)
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(exchange.getResponse()) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
// 修改响应体内容
}
};
exchange = exchange.mutate().response(decoratedResponse).build();四、请求转发
4.1 NettyRoutingFilter
java
// 默认的 HTTP 转发过滤器
public class NettyRoutingFilter implements GlobalFilter, Ordered {
private final HttpClient httpClient; // Reactor Netty HttpClient
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// 1. 构建转发请求
ServerHttpRequest request = exchange.getRequest();
URI uri = route.getUri();
// 2. 使用 WebClient 构建转发请求
Flux<HttpClientResponse> responseFlux = httpClient
.headers(headers -> {
// 透传请求头(可配置)
headers.add("X-Forwarded-For", request.getRemoteAddress().toString());
})
.request(HttpMethod.valueOf(request.getMethod().name()))
.uri(uri.toString()) // 转发 URI
.send((req, nettyOutbound) -> {
// 发送请求体
return nettyOutbound.send(request.getBody());
})
.responseConnection((resp, connection) -> {
// 3. 将下游响应写回原始响应
ServerHttpResponse serverResponse = exchange.getResponse();
serverResponse.setStatusCode(HttpStatus.valueOf(resp.status().code()));
// 透传响应头
resp.responseHeaders().forEach(entry ->
serverResponse.getHeaders().add(entry.getKey(), entry.getValue()));
return serverResponse.writeWith(connection.inbound().receive());
});
return responseFlux.then();
}
}4.2 ForwardRoutingFilter
java
// 本地转发过滤器(forward:// 协议)
public class ForwardRoutingFilter implements GlobalFilter, Ordered {
private final HandlerMapping handlerMapping;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
URI routeUri = route.getUri();
if (!"forward".equals(routeUri.getScheme())) {
return chain.filter(exchange); // 非 forward 协议,跳过
}
// 使用 WebFlux 的 HandlerMapping 本地处理
return handlerMapping.getHandler(exchange)
.flatMap(handler -> {
if (handler instanceof WebHandler) {
return ((WebHandler) handler).handle(exchange);
}
return Mono.error(new IllegalStateException("..."));
});
}
}五、启动与初始化
5.1 GatewayAutoConfiguration
java
@Configuration
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(
FilteringWebHandler filteringWebHandler,
RouteLocator routeLocator) {
return new RoutePredicateHandlerMapping(
filteringWebHandler, routeLocator);
}
@Bean
public FilteringWebHandler filteringWebHandler(
List<GlobalFilter> globalFilters) {
return new FilteringWebHandler(globalFilters);
}
@Bean
@ConditionalOnMissingBean
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator() {
return new PropertiesRouteDefinitionLocator();
}
}5.2 过滤器初始化顺序
java
// 内置 GlobalFilter 默认 Order
// 数值由各过滤器的 getOrder() 方法定义
public class NettyRoutingFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE; // 最后执行
}
}
public class ForwardRoutingFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
public class AdaptCachedBodyGlobalFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 1000; // 最先执行
}
}六、总结
| 组件 | 职责 | 关键方法/类 |
|---|---|---|
RoutePredicateHandlerMapping | 路由匹配 | getHandlerInternal() → lookupRoute() |
FilteringWebHandler | 过滤器链执行 | handle() → DefaultGatewayFilterChain |
ServerWebExchange | 请求/响应上下文 | getRequest(), getResponse(), getAttributes() |
NettyRoutingFilter | HTTP 转发 | Reactor Netty HttpClient |
ForwardRoutingFilter | 本地转发 | HandlerMapping.getHandler() |
| 过滤器链 | 递归执行 | filter(exchange, chain) |
| 请求包装 | 装饰器模式 | exchange.mutate().request/response() |
参考链接: