RoutePredicateHandlerMapping#getHandlerInternal
webflux的入口是DispatcherHandler,他这里会调用HandlerMapping的getHandler方法。AbstractHandlerMapping实现了HandlerMapping接口,他有个抽象方法getHandlerInternal需要子类实现。
RoutePredicateHandlerMapping继承了AbstractHandlerMapping,所以我们的重点就是他的getHandlerInternal方法。这里面就是用来处理是否有对应的Route。
这个方法,其实主要调用lookupRoute方法。
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);
}
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) + "]");
}
})));
}
RoutePredicateHandlerMapping#lookupRoute
我们可以看到他有个r.getPredicate().apply这样的代码,他这个apply最终会调用每个Predicate的test方法,返回false或者true。
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes()
// individually filter routes so that filterWhen error delaying is not a
// problem
.concatMap(route -> Mono.just(route).filterWhen(r -> {
// add the current route we are testing
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
return r.getPredicate().apply(exchange);
})
// 其他略
}
DefaultAsyncPredicate#apply
在这里,会把每个Predicate的test方法调用过去。
public Publisher<Boolean> apply(T t) {
return Mono.just(delegate.test(t));
}
FilteringWebHandler#handle
我们已经从上面的方法中拿到了一个Route(没有就不继续了),那就开始调用Filter。
DispatcherHandler在调用完handlerMappings后,会调用他的invokeHandler方法。
private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
if (this.handlerAdapters != null) {
for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
if (handlerAdapter.supports(handler)) {
return handlerAdapter.handle(exchange, handler);
}
}
}
return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
}
然后会调用webHandler.handle方法。
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
WebHandler webHandler = (WebHandler) handler;
Mono<Void> mono = webHandler.handle(exchange);
return mono.then(Mono.empty());
}
我们的FilteringWebHandler就是一个WebHandler,我们看看他的handle方法。
他会先获取对应Route的Filters,再和通用的Filters合并排序,最后开始Filters的调用链。
public Mono<Void> handle(ServerWebExchange exchange) {
// 获取Route
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
// 取出Filters
List<GatewayFilter> gatewayFilters = route.getFilters();
// 加入通用的Filters
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
combined.addAll(gatewayFilters);
// TODO: needed or cached?
// 排序
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled()) {
logger.debug("Sorted gatewayFilterFactories: " + combined);
}
// 调用链
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
整体流程
这边忽略了DispatcherHandler部分
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。