spring cloud gateway源码(五)请求流程

spring Cloud gateway的请求流程图如下:

一、Predicate

在Spring Cloud Gateway中,在走完自定义的Filter后,会找到对应的handler方法,而在Spring Cloud Gateway中,对应的Handler就是根据Route去寻找的,

@Override
public Mono<Object> getHandler(ServerWebExchange exchange) {
   return getHandlerInternal(exchange).map(handler -> {
      if (CorsUtils.isCorsRequest(exchange.getRequest())) {
         CorsConfiguration configA = this.globalCorsConfigSource.getCorsConfiguration(exchange);
         CorsConfiguration configB = getCorsConfiguration(handler, exchange);
         CorsConfiguration config = (configA != null ? configA.combine(configB) : configB);
         if (!getCorsProcessor().process(config, exchange) ||
               CorsUtils.isPreFlightRequest(exchange.getRequest())) {
            return REQUEST_HANDLED_HANDLER;
         }
      }
      return handler;
   });
}
   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);

可以看到寻找路由的方法是 lookupRoute(exchange),我们进入看下

protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
   return this.routeLocator.getRoutes()
         .filterWhen(route ->  {
            // add the current route we are testing
            exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, route.getId());
            return route.getPredicate().apply(exchange);
         })

最后一行可以看到,寻找匹配路由的方式是,通过exchange去匹配route的Predicate属性,找到合适的route,predicate是路径的匹配类,其内容类似下面这样:

可以看到是用的Spring的pathPattern类做的匹配。

二、route

三、filter

在后面调用invokeHandler方法的时候,就会调用FilteringWebHandler的handle()方法:

扫描二维码关注公众号,回复: 2784426 查看本文章
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
   Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
   List<GatewayFilter> gatewayFilters = route.getFilters();

   List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
   combined.addAll(gatewayFilters);
   //TODO: needed or cached?
   AnnotationAwareOrderComparator.sort(combined);

   logger.debug("Sorted gatewayFilterFactories: "+ combined);

   return new DefaultGatewayFilterChain(combined).filter(exchange);
}

上面的方法中,将GlobalFilter封装成GatewayFIlter类型,并放入调用链中调用。

四、predicate和filter的初始化

看了流程后,我们就说下,predicate和filter是在什么地方初始化的。

在DiscoveryClientRouteDefinitionLocator类中我们看到,predicate和filter是从properties中获取到的。properties这个bean的创建方法是在GatewayDiscoveryClientAutoConfiguration类中。

	@Bean
	public DiscoveryLocatorProperties discoveryLocatorProperties() {
		DiscoveryLocatorProperties properties = new DiscoveryLocatorProperties();
		properties.setPredicates(initPredicates());
		properties.setFilters(initFilters());
		return properties;
	}

	public static List<PredicateDefinition> initPredicates() {
		ArrayList<PredicateDefinition> definitions = new ArrayList<>();
		// TODO: add a predicate that matches the url at /serviceId?

		// add a predicate that matches the url at /serviceId/**
		PredicateDefinition predicate = new PredicateDefinition();
		predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
		predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
		definitions.add(predicate);
		return definitions;
	}

	public static List<FilterDefinition> initFilters() {
		ArrayList<FilterDefinition> definitions = new ArrayList<>();

		// add a filter that removes /serviceId by default
		FilterDefinition filter = new FilterDefinition();
		filter.setName(normalizeFilterFactoryName(RewritePathGatewayFilterFactory.class));
		String regex = "'/' + serviceId + '/(?<remaining>.*)'";
		String replacement = "'/${remaining}'";
		filter.addArg(REGEXP_KEY, regex);
		filter.addArg(REPLACEMENT_KEY, replacement);
		definitions.add(filter);

		return definitions;
	}

可以看到每个路由都有使用到的是一个predicate:PathRoutePredicateFactory。一个filter:RewritePathGatewayFilterFactory

猜你喜欢

转载自blog.csdn.net/lz710117239/article/details/81293757