H5W3
当前位置:H5W3 > java > 正文

【Java】gateway – 调用

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部分
【Java】gateway - 调用

本文地址:H5W3 » 【Java】gateway – 调用

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址