Web
处理流程1、请求入口
//org.springframework.web.server.handler.FilteringWebHandler#handle
public Mono<Void> handle(ServerWebExchange exchange) {
//chain类型:DefaultWebFilterChain
return this.chain.filter(exchange);
}
1582624312263
2、执行WebFilterChain
调用链
//org.springframework.web.server.handler.DefaultWebFilterChain#filter
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() ->
this.currentFilter != null && this.next != null ?
this.currentFilter.filter(exchange, this.next) :
this.handler.handle(exchange));
}
把每个WebFilter
都包装成一个DefaultWebFilterChain
,其中包含两个主要属性:当前封装的WebFilter
以及下一个chain
:
private final WebFilter currentFilter;//当前WebFilter实例
private final DefaultWebFilterChain next;//下一个chain实例
这样把所有的WebFilter
串成一个chain
链,触发第一个DefaultWebFilterChain.filter()
方法后就会按照chain
链的顺序执行下去,最后一个WebFilter
执行完成后,再去执行WebHandler
,默认类型是:org.springframework.web.reactive.DispatcherHandler
。
总结起来就是,把WebFilter
执行完成后,再去调用DispatcherHandler.handle(exchange)
方法。
3、请求总控制器DispatcherHandler
//org.springframework.web.reactive.DispatcherHandler#handle
public Mono<Void> handle(ServerWebExchange exchange) {
//校验handlerMappings是否为空
if (this.handlerMappings == null) {
return createNotFoundError();
}
return Flux.fromIterable(this.handlerMappings)//遍历handlerMappings集合进行请求处理
.concatMap(mapping -> mapping.getHandler(exchange))//通过mapping获取对应的handler
.next()
.switchIfEmpty(createNotFoundError())
.flatMap(handler -> invokeHandler(exchange, handler))//调用handler处理
.flatMap(result -> handleResult(exchange, result));
}
1582104568844
遍历HandlerMapping
获取mapping
对应的handler
,此处会找到RoutePredicateHandlerMapping
,并获得handler
(FilteringWebHandler
)。我们来看下RoutePredicateHandlerMapping#getHandler
方法执行逻辑。
首先,getHandler
定义在父类AbstractHandlerMapping
中,见下:
public Mono<Object> getHandler(ServerWebExchange exchange) {
return getHandlerInternal(exchange).map(handler -> {//调用子类中getHandlerInternal()获取handler
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
}
if (CorsUtils.isCorsRequest(exchange.getRequest())) {//判断是否跨域
CorsConfiguration configA = this.corsConfigurationSource.getCorsConfiguration(exchange);
CorsConfiguration configB = getCorsConfiguration(handler, exchange);
CorsConfiguration config = (configA != null ? configA.combine(configB) : configB);
if (!getCorsProcessor().process(config, exchange) ||
CorsUtils.isPreFlightRequest(exchange.getRequest())) {
return REQUEST_HANDLED_HANDLER;
}
}
return handler;
});
}
RoutePredicateHandlerMapping#getHandlerInternal
:根据exchange
匹配对应的Route
,并放置到exchange
的attribute
中,同时返回org.springframework.cloud.gateway.handler.FilteringWebHandler
类型的hanler
:
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
// don't handle requests on management port if set and different than server port
if (this.managementPortType == DIFFERENT && this.managementPort != null
&& exchange.getRequest().getURI().getPort() == this.managementPort) {
return Mono.empty();
}
exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getSimpleName());
return lookupRoute(exchange)
// .log("route-predicate-handler-mapping", Level.FINER) //name this
.flatMap((Function<Route, Mono<?>>) r -> {
exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
if (logger.isDebugEnabled()) {
logger.debug(
"Mapping [" + getExchangeDesc(exchange) + "] to " + r);
}
//将匹配到的Route放置到Attribute中
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
return Mono.just(webHandler);
}).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
if (logger.isTraceEnabled()) {
logger.trace("No RouteDefinition found for ["
+ getExchangeDesc(exchange) + "]");
}
})));
}
接下来看下匹配Route
逻辑代码lookupRoute()
:
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes()//调用CachingRouteLocator#getRoutes从缓存中获取routes
.concatMap(route -> Mono.just(route).filterWhen(r -> {
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());//
return r.getPredicate().apply(exchange);//通过路由断言Predicate过滤掉不可用路由信息
}).doOnError(e -> logger.error(
"Error applying predicate for route: " + route.getId(), e))
.onErrorResume(e -> Mono.empty()))
.next()
.map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("Route matched: " + route.getId());
}
validateRoute(route, exchange);
return route;
});
}
getHandlerInternal
大致逻辑: 1、通过CachingRouteLocator#getRoutes
从缓存中获取routes
,routes
加载流程上次《Route
加载流程》一节已分析过; 2、遍历routes
,并通过Route
中的断言Predicate
过滤掉不可用路由; 3、查找到路由信息后,通过exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r)
设置到上下文环境中; 4、返回Gateway
自定义的WebHandler(FilteringWebHandler)
;
Gateway
处理流程4、执行handler
RoutePredicateHandlerMapping
获得org.springframework.cloud.gateway.handler.FilteringWebHandler
,然后执行invokeHandler()
:
private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
if (this.handlerAdapters != null) {
//遍历handlerAdapter列表,通过supports()方法找到支持该handler的Adapter
for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
if (handlerAdapter.supports(handler)) {
return handlerAdapter.handle(exchange, handler);
}
}
}
return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
}
1582162794216
如上图显示,只有SimpleHandlerAdapter
支持FilteringWebHandler
,SimpleHandlerAdapter
处理很简单,将handler
转型成WebHandler
,然后直接调用webHandler#handle
:
//org.springframework.web.reactive.result.SimpleHandlerAdapter#handle
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
WebHandler webHandler = (WebHandler) handler;
Mono<Void> mono = webHandler.handle(exchange);
return mono.then(Mono.empty());
}
5、Gateway
核心控制器FilteringWebHandler
此FilteringWebHandler
非前面说spring-web
包中的FilteringWebHandler
,而是位于gateway-core
模块下,是请求进入gateway
模块的核心入口。
//org.springframework.cloud.gateway.handler.FilteringWebHandler#handle
public Mono<Void> handle(ServerWebExchange exchange) {
//获取匹配的Route,该Route是在RoutePredicateHandlerMapping中匹配并放置到exchange的attribute中的
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
//获取配置的过滤器
List<GatewayFilter> gatewayFilters = route.getFilters();
//获取全局过滤器
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
//将两种过滤器合并一起
combined.addAll(gatewayFilters);
//对过滤器进行排序
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled()) {
logger.debug("Sorted gatewayFilterFactories: " + combined);
}
//将过滤器封装到chain并执行filter方法
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
大致工作: 1、获取之前
RoutePredicateHandlerMapping
中放置到exchange
的attribute
中的Route
对象; 2、然后从Route中获取的GatewayFilter和全局过滤器GlobalFilter进行合入并排序; 3、将所有的Filter包装成DefaultGatewayFilterChain,然后执行filter()方法;
1582163465104
接下来来分析下DefaultGatewayFilterChain
执行流程,代码见下:
//DefaultGatewayFilterChain#filter
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
return filter.filter(exchange, chain);
}
else {
return Mono.empty(); // complete
}
});
}
从filter()
方法中的代码逻辑可以看出,这里也是将所有的GatewayFilter
进行包装构建成调用链chain
,然后按照调用链顺序一个个执行GatewayFilter
,这里的**chain
调用链构建原理参照上面WebFilter
调用链**创建过程。
image-20200227004515360
Gateway
请求处理流程大致可以绘制成上面图,其中浅绿色为spring-web
部分流程,然后进入到gateway
代码部分(浅蓝色部分);其中,交界处RoutePredicateHandler
会从CachingRouteLocator
缓存的routes
,然后基于Predicate
进行匹配过滤出当前符合当前请求的Route
,然后开始真正进入Gateway
处理流程,基于GatewayFilter
扩展出各种业务功能。