gateway路由匹配

126 阅读4分钟

1.DispatcherHandler

DefaultWebFilterChain

同ApplicationFilterChain (servlet协议下 过滤器链的包装对象), DefaultWebFilterChain 这里也维护了 filters 和 handler(ApplicationFilterChain里是servlet)

public class DefaultWebFilterChain implements WebFilterChain {
    private final List<WebFilter> allFilters;
    private final WebHandler handler;
    private final WebFilter currentFilter;
    private final DefaultWebFilterChain chain;

    public DefaultWebFilterChain(WebHandler handler, List<WebFilter> filters) {
        this.allFilters = Collections.unmodifiableList(filters);
        this.handler = handler;
        DefaultWebFilterChain chain = initChain(filters, handler);
        this.currentFilter = chain.currentFilter;
        this.chain = chain.chain;
    }

    private static DefaultWebFilterChain initChain(List<WebFilter> filters, WebHandler handler) {
        //这里的逻辑是逆序封装  比如 原过滤器链的顺序为 1,2,3,4   封装完毕后的 chain 一共有5层,currentFilter 分别为1,2,3,4,null ,这样就可以达到顺序执行的效果   ApplicationFilterChain是自身维护了两个下标,这里是chain维护了下一个执行对象
        DefaultWebFilterChain chain = new DefaultWebFilterChain(filters, handler, (WebFilter)null, (DefaultWebFilterChain)null);
        for(ListIterator iterator = filters.listIterator(filters.size()); iterator.hasPrevious(); chain = new DefaultWebFilterChain(filters, handler, (WebFilter)iterator.previous(), chain)) {
        }
        return chain;
    }

 

    private DefaultWebFilterChain(List<WebFilter> allFilters, WebHandler handler, @Nullable WebFilter currentFilter, @Nullable DefaultWebFilterChain chain) {
        this.allFilters = allFilters;
        this.currentFilter = currentFilter;
        this.handler = handler;
        this.chain = chain;
    }

    public Mono<Void> filter(ServerWebExchange exchange) {
        return Mono.defer(() -> {
            //顺序执行过滤器链 过滤器执行完毕后 调用handler.handle ,进入DispatcherHandler表演时间
            return this.currentFilter != null && this.chain != null ? this.invokeFilter(this.currentFilter, this.chain, exchange) : this.handler.handle(exchange);
      });
    }

   private Mono<Void> invokeFilter(WebFilter current, DefaultWebFilterChain chain, ServerWebExchange exchange) {
      String currentName = current.getClass().getName();
      return current.filter(exchange, chain).checkpoint(currentName + " [DefaultWebFilterChain]");
    }
}

DispatcherHandler

同servlet协议下web工程,reactive web框架 :webflux 的核心转发类   叫 DispatcherHandler ,一样的具备 handlerMappings,handlerAdapters 进行路由的匹配和调用

public class DispatcherHandler implements WebHandler, ApplicationContextAware {
    private List<HandlerMapping> handlerMappings;
    private List<HandlerAdapter> handlerAdapters;
    private List<HandlerResultHandler> resultHandlers;
    public void setApplicationContext(ApplicationContext applicationContext) {
        //initializeBean 阶段 postProcessBeforeInitialization 触发 下方初始化
        this.initStrategies(applicationContext);
    }

    protected void initStrategies(ApplicationContext context) {
        //WebEndpointReactiveHandlerMapping
        //ControllerEndpointHandlerMapping
        //RequestMappingHandlerMapping
        //RouterFunctionMapping
        //ResourceHandlerMapping
        //RoutePredicateHandlerMapping    作为网关 我们这里只关心这个HandlerMapping解析器
        //WelcomePageRouterFunctionMapping

        Map<String, HandlerMapping> mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
        ArrayList<HandlerMapping> mappings = new ArrayList(mappingBeans.values());
        AnnotationAwareOrderComparator.sort(mappings);
        this.handlerMappings = Collections.unmodifiableList(mappings);
        Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
        //RequestMappingHandlerAdapter
        //HandlerFunctionAdapter
        //SimpleHandlerAdapter
        this.handlerAdapters = new ArrayList(adapterBeans.values());
        AnnotationAwareOrderComparator.sort(this.handlerAdapters);
        Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerResultHandler.class, true, false);
        //ResponseEntityResultHandler
        //ResponseBodyResultHandler
        //ViewResolutionResultHandler
        //ServerResponseResultHandler
        this.resultHandlers = new ArrayList(beans.values());
        AnnotationAwareOrderComparator.sort(this.resultHandlers);
    }

    //对标DispatchServlet 的 doDispatch方法
    public Mono<Void> handle(ServerWebExchange exchange) {
      return this.handlerMappings == null ? this.createNotFoundError() : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
                //同DispatchServlet 遍历所有的HandlerMapping 找到合适的路由 从而找到对应的处理器,这里取第一个适配的handler
                return mapping.getHandler(exchange);
            }).next().switchIfEmpty(this.createNotFoundError()).flatMap((handler) -> {
                return this.invokeHandler(exchange, handler);
            }).flatMap((result) -> {
                return this.handleResult(exchange, result);
            });
    }

    //HandlerAdaptor 执行handler
    private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
        if (this.handlerAdapters != null) {
            Iterator var3 = this.handlerAdapters.iterator();
            while(var3.hasNext()) {
                  //这里返回 FilteringWebHandler对象   由SimpleHandlerAdapter执行
                  HandlerAdapter handlerAdapter = (HandlerAdapter)var3.next();
                  if (handlerAdapter.supports(handler)) {
                      return handlerAdapter.handle(exchange, handler);
                  }
              }
          }
         return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
      }
  }

1.获取handler

AbstractHandlerMapping#getHandler
public Mono<Object> getHandler(ServerWebExchange exchange) {
    //这里有各自的实现类 我们看RoutePredicateHandlerMapping  这里返回的是维护了List<GatewayFilter> globalFilters 全局过滤器 FilteringWebHandler 对象
    return this.getHandlerInternal(exchange).map((handler) -> {
        ServerHttpRequest request = exchange.getRequest();
        return handler;
    });
}

RoutePredicateHandlerMapping#getHandlerInternal

protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
    if (this.managementPortType == RoutePredicateHandlerMapping.ManagementPortType.DIFFERENT && this.managementPort != null && exchange.getRequest().getURI().getPort() == this.managementPort) {
        return Mono.empty();
    } else {
        exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_HANDLER_MAPPER_ATTR, this.getSimpleName());
        //寻找路由
        return this.lookupRoute(exchange).flatMap((r) -> {
   exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
            //这里将匹配中的Route对象 以 gatewayRoute 作key,存入了当前请求、返回对象,也就ServerWebExchange 的map(servlet下是request,这里包装到一起了)中
            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR, r);
            //返回 FilteringWebHandler webHandler,内部维护List<GatewayFilter> globalFilters 全局过滤器
            return Mono.just(this.webHandler);
        }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
            exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
        })));
    }
}

RoutePredicateHandlerMapping#lookupRoute

protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
    //routeLocator  -> CachingRouteLocator  基于缓存的路由定位器,包装了CompositeRouteLocator,而CompositeRouteLocator则组合了RouteDefinitionRouteLocator
    //详情见下图
    return this.routeLocator.getRoutes().concatMap((route) -> {
        return Mono.just(route).filterWhen((r) -> {
    exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
            //根据Predicate循环进行匹配 这里是链条的形式调用
            return (Publisher)r.getPredicate().apply(exchange);
        }).doOnError((e) -> {
           //打印
        }).onErrorResume((e) -> {
            return Mono.empty();
        });
    //返回第一个命中的
    }).next().map((route) -> {
        //空方法 没有实现
        this.validateRoute(route, exchange);
        return route;
    });
}

image.png

RouteDefinitionRouteLocator#getRoutes
public Flux<Route> getRoutes() {
    //RouteDefinition 转化为Route对象
    Flux<Route> routes = this.routeDefinitionLocator.getRouteDefinitions().map(this::convertToRoute);
    if (!this.gatewayProperties.isFailOnRouteDefinitionError()) {
        routes = routes.onErrorContinue((error, obj) -> {
        });
    }
    return routes.map((route) -> {
        return route;
    });


CompositeRouteDefinitionLocator#getRouteDefinitions

public Flux<RouteDefinition> getRouteDefinitions() {
    //这里getRouteDefinitions是每个RouteDefinitionLocator各自的实现,在这里按顺序组装起来,id为空的话填充随机数
    return this.delegates.flatMapSequential(RouteDefinitionLocator::getRouteDefinitions).flatMap((routeDefinition) -> {
        return routeDefinition.getId() == null ? this.randomId().map((id) -> {
            routeDefinition.setId(id);
            return routeDefinition;
        }) : Mono.just(routeDefinition);
    });
}

PropertiesRouteDefinitionLocator#getRouteDefinitions
//PropertiesRouteDefinitionLocator的实现非常简单 直接从properties里读取到的集合中拿,只依赖了一个@ConfigurationProperties("spring.cloud.gateway")就搞定了
public Flux<RouteDefinition> getRouteDefinitions() {
    return Flux.fromIterable(this.properties.getRoutes());
}

RouteDefinitionRouteLocator#convertToRoute
private Route convertToRoute(RouteDefinition routeDefinition) {
    //组合Predicate
    AsyncPredicate<ServerWebExchange> predicate = this.combinePredicates(routeDefinition);
    //获取defaultFilters + 自身RouteDefinition 中定义的 FilterDefinition  对应的实例(同上也是从工厂获得)  ,排序后返回
    List<GatewayFilter> gatewayFilters = this.getFilters(routeDefinition);
    return ((AsyncBuilder)Route.async(routeDefinition).asyncPredicate(predicate).replaceFilters(gatewayFilters)).build();
}

RouteDefinitionRouteLocator#combinePredicates
//这里组合Predicates比较有意思
private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
    List<PredicateDefinition> predicates = routeDefinition.getPredicates();
    if (predicates != null && !predicates.isEmpty()) {
        //取出第一个PredicateDefinition lookup方法是从对应工厂中找到 获取 Predicate对象 再封装成 DefaultAsyncPredicate,DefaultAsyncPredicate内部维护的就是Predicate,apply方法就是调用 Predicate.test 获取boolean返回
        AsyncPredicate<ServerWebExchange> predicate = this.lookup(routeDefinition, (PredicateDefinition)predicates.get(0));
        AsyncPredicate found;
        //predicate.and(other) 是将自身,及两一个对象封装成 AndAsyncPredicate对象,内部维护了一个left ,right指针,自身作为新对象的left,other作为right
        //这样 循环结束后,返回一个AndAsyncPredicate对象,this.left.left.left .... 可以追到第一个Predicate对象,右指针则是最后一个 Predicate对象
        for(Iterator var4 = predicates.subList(1, predicates.size()).iterator(); var4.hasNext(); predicate = predicate.and(found)) {
            PredicateDefinition andPredicate = (PredicateDefinition)var4.next();
            found = this.lookup(routeDefinition, andPredicate);
        }
        return predicate;
    } else {
        return AsyncPredicate.from((exchange) -> {
            return true;
        });
    }
}

AsyncPredicate.AndAsyncPredicate#apply
public Publisher<Boolean> apply(T t) {
    return Mono.from((Publisher)this.left.apply(t)).flatMap((result) -> {
        //有一个不通过就返回了 否则找右指针 执行完毕后 会上上一个节点的右指针继续执行
        return !result ? Mono.just(false) : Mono.from((Publisher)this.right.apply(t));
    });
}

2.执行handler

FilteringWebHandler#handle

public Mono<Void> handle(ServerWebExchange exchange) {
    //获取之前存放的 Route对象
    Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
    List<GatewayFilter> gatewayFilters = route.getFilters();
    List<GatewayFilter> combined = new ArrayList(this.globalFilters);
    //全局过滤器 + defaultFilters + GatewayFilter 组合 排序
    combined.addAll(gatewayFilters);
    AnnotationAwareOrderComparator.sort(combined);
    return (new FilteringWebHandler.DefaultGatewayFilterChain(combined)).filter(exchange);

}

当前请求过滤器链

image.png

DefaultGatewayFilterChain#filter

public Mono<Void> filter(ServerWebExchange exchange) {
    return Mono.defer(() -> {
        //index 从0开始
        if (this.index < this.filters.size()) {
            GatewayFilter filter = (GatewayFilter)this.filters.get(this.index);
            //传递this,实际上是把filters传过去了,下标+1, 后续的  return chain.filter(exchange);  就能找到下一个过滤器继续执行
            FilteringWebHandler.DefaultGatewayFilterChain chain = new FilteringWebHandler.DefaultGatewayFilterChain(this, this.index + 1);
            return filter.filter(exchange, chain);
        } else {
            return Mono.empty();
        }
    });
}