关于java:gateway-调用

5次阅读

共计 3183 个字符,预计需要花费 8 分钟才能阅读完成。

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 局部

正文完
 0