咱们从spring.factories开始,次要是GatewayAutoConfiguration,这里次要加载CompositeRouteDefinitionLocator、RouteDefinitionRouteLocator、FilteringWebHandler、RoutePredicateHandlerMapping、RouteRefreshListener、CachingRouteLocator等。
RouteLocator和RouteDefinitionLocator的作用在上一篇曾经提过了,FilteringWebHandler、RoutePredicateHandlerMapping这两个等调用的时候讲,这边先晓得他们会在这里加载。咱们次要看看RouteRefreshListener和CachingRouteLocator。

RouteRefreshListener

RouteRefreshListener实现了ApplicationListener接口,所以他会调用onApplicationEvent办法,在合乎某些条件下,会调用reset办法,这个思路和zuul是一样的。所以动静的刷新也能够调用他的事件来触发。

public void onApplicationEvent(ApplicationEvent event) {    if (event instanceof ContextRefreshedEvent            || event instanceof RefreshScopeRefreshedEvent            || event instanceof InstanceRegisteredEvent) {        reset();    }    else if (event instanceof ParentHeartbeatEvent) {        ParentHeartbeatEvent e = (ParentHeartbeatEvent) event;        resetIfNeeded(e.getValue());    }    else if (event instanceof HeartbeatEvent) {        HeartbeatEvent e = (HeartbeatEvent) event;        resetIfNeeded(e.getValue());    }}

咱们看看reset办法,他其实就是公布了一个RefreshRoutesEvent事件。

private void reset() {    this.publisher.publishEvent(new RefreshRoutesEvent(this));}

CachingRouteLocator

CachingRouteLocator就是用来接管RefreshRoutesEvent事件的,他实现了ApplicationListener<RefreshRoutesEvent>接口。咱们看看他的onApplicationEvent办法。

public void onApplicationEvent(RefreshRoutesEvent event) {    try {        fetch().collect(Collectors.toList()).subscribe(list -> Flux.fromIterable(list)                .materialize().collect(Collectors.toList()).subscribe(signals -> {                    applicationEventPublisher                            .publishEvent(new RefreshRoutesResultEvent(this));                    cache.put(CACHE_KEY, signals);                }, throwable -> handleRefreshError(throwable)));    }    catch (Throwable e) {        handleRefreshError(e);    }}

他先会调用fetch办法,这里实际上就是调用CompositeRouteLocator#getRoutes,最初再调用RouteDefinitionRouteLocator#getRoutes。

private Flux<Route> fetch() {    return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);}

RouteDefinitionRouteLocator#getRoutes

这个办法能够看到他是获取RouteDefinition的汇合,而后再调用convertToRoute办法,在这个办法里,把RouteDefinition转为Route。

@Overridepublic Flux<Route> getRoutes() {    Flux<Route> routes = this.routeDefinitionLocator.getRouteDefinitions()            .map(this::convertToRoute);    // 其余略}

RouteDefinitionRouteLocator#convertToRoute

在这里把RouteDefinition转为Route,次要是解析Predicate和GatewayFilter,咱们在上一篇曾经晓得了他会通过工厂类来解决。combinePredicates办法就是解决Predicate的,getFilters是解决Filter的。

private Route convertToRoute(RouteDefinition routeDefinition) {    AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);    List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);    return Route.async(routeDefinition).asyncPredicate(predicate)            .replaceFilters(gatewayFilters).build();}

RouteDefinitionRouteLocator#combinePredicates

在这里就是把RouteDefinition的predicate转为Route须要的Predicate。这里首先会创立一个Predicate,而后再把残余的合并,造成了一个left、right的构造。结构图在上一篇曾经说过了。
lookup办法就是通过工厂类创立Predicate的中央。

private AsyncPredicate<ServerWebExchange> combinePredicates(        RouteDefinition routeDefinition) {    List<PredicateDefinition> predicates = routeDefinition.getPredicates();    if (predicates == null || predicates.isEmpty()) {        // this is a very rare case, but possible, just match all        return AsyncPredicate.from(exchange -> true);    }    // 创立第一个Predicate    AsyncPredicate<ServerWebExchange> predicate = lookup(routeDefinition,            predicates.get(0));    // 把残余的进行合并    for (PredicateDefinition andPredicate : predicates.subList(1,            predicates.size())) {        AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition,                andPredicate);        predicate = predicate.and(found);    }    return predicate;}

RouteDefinitionRouteLocator#lookup

这个办法里,首先先通过配置的名称,获取对应的RoutePredicateFactory,而后组装config信息,最初通过factory.applyAsync创立Predicate。

private AsyncPredicate<ServerWebExchange> lookup(RouteDefinition route,        PredicateDefinition predicate) {    RoutePredicateFactory<Object> factory = this.predicates.get(predicate.getName());    if (factory == null) {        throw new IllegalArgumentException(                "Unable to find RoutePredicateFactory with name "                        + predicate.getName());    }    if (logger.isDebugEnabled()) {        logger.debug("RouteDefinition " + route.getId() + " applying "                + predicate.getArgs() + " to " + predicate.getName());    }    // @formatter:off    Object config = this.configurationService.with(factory)            .name(predicate.getName())            .properties(predicate.getArgs())            .eventFunction((bound, properties) -> new PredicateArgsEvent(                    RouteDefinitionRouteLocator.this, route.getId(), properties))            .bind();    // @formatter:on    return factory.applyAsync(config);}

RouteDefinitionRouteLocator#getFilters

这个是解决Filter的中央,他次要是通过loadGatewayFilters办法来获取对应的Filter。

private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {    List<GatewayFilter> filters = new ArrayList<>();    // TODO: support option to apply defaults after route specific filters?    if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {        filters.addAll(loadGatewayFilters(DEFAULT_FILTERS,                new ArrayList<>(this.gatewayProperties.getDefaultFilters())));    }    if (!routeDefinition.getFilters().isEmpty()) {        filters.addAll(loadGatewayFilters(routeDefinition.getId(),                new ArrayList<>(routeDefinition.getFilters())));    }    AnnotationAwareOrderComparator.sort(filters);    return filters;}

RouteDefinitionRouteLocator#loadGatewayFilters

这个设计形式跟下面相似,也是通过配置信息的名称,获取对应的GatewayFilterFactory,而后封装configuration信息,通过factory.apply创立一个Filter。

List<GatewayFilter> loadGatewayFilters(String id,        List<FilterDefinition> filterDefinitions) {    ArrayList<GatewayFilter> ordered = new ArrayList<>(filterDefinitions.size());    for (int i = 0; i < filterDefinitions.size(); i++) {        FilterDefinition definition = filterDefinitions.get(i);        GatewayFilterFactory factory = this.gatewayFilterFactories                .get(definition.getName());        if (factory == null) {            throw new IllegalArgumentException(                    "Unable to find GatewayFilterFactory with name "                            + definition.getName());        }        if (logger.isDebugEnabled()) {            logger.debug("RouteDefinition " + id + " applying filter "                    + definition.getArgs() + " to " + definition.getName());        }        // @formatter:off        Object configuration = this.configurationService.with(factory)                .name(definition.getName())                .properties(definition.getArgs())                .eventFunction((bound, properties) -> new FilterArgsEvent(                        // TODO: why explicit cast needed or java compile fails                        RouteDefinitionRouteLocator.this, id, (Map<String, Object>) properties))                .bind();        // @formatter:on        // some filters require routeId        // TODO: is there a better place to apply this?        if (configuration instanceof HasRouteId) {            HasRouteId hasRouteId = (HasRouteId) configuration;            hasRouteId.setRouteId(id);        }        GatewayFilter gatewayFilter = factory.apply(configuration);        if (gatewayFilter instanceof Ordered) {            ordered.add(gatewayFilter);        }        else {            ordered.add(new OrderedGatewayFilter(gatewayFilter, i + 1));        }    }    return ordered;}

整体流程