文章目录


1 介绍

spring cloud gateway源码中,内置了大量的Predicate工具,用于处理不同情况下的断言信息,
在这里插入图片描述
对于每一个断言参数的配置,可以参考文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-request-predicates-factories

2 校验配置

对于每一个 断言(Predicate),其配置的方式都有两种,
Shortcut Configuration,Fully Expanded Arguments
第一种方式,通过单一text配置

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

gateway源码在实例化配置时,通过public PredicateDefinition(String text)构造函数去解析

public PredicateDefinition(String text) {
		int eqIdx = text.indexOf('=');
		if (eqIdx <= 0) {
			throw new ValidationException("Unable to parse PredicateDefinition text '"
					+ text + "'" + ", must be of the form name=value");
		}
		setName(text.substring(0, eqIdx));

		String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), ",");

		for (int i = 0; i < args.length; i++) {
			this.args.put(NameUtils.generateName(i), args[i]);
		}
	}

通过"="进行name,和args拆分,然后再通过:String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), “,”); 解析对应的args参数,
Fully Expanded Arguments即采用标准的yml格式进行配置:

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

gateway源码中,首先会去获取所有的RoutePredicateFactory类型的Predicates,

public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
			List<GatewayFilterFactory> GatewayFilters,
			List<RoutePredicateFactory> predicates,
			RouteDefinitionLocator routeDefinitionLocator,
			@Qualifier("webFluxConversionService") ConversionService conversionService) {
		return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,
				GatewayFilters, properties, conversionService);
	}

然后实例化RouteLocator类型的RouteDefinitionRouteLocator

public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,
			List<RoutePredicateFactory> predicates,
			List<GatewayFilterFactory> gatewayFilterFactories,
			GatewayProperties gatewayProperties, ConversionService conversionService) {
		this.routeDefinitionLocator = routeDefinitionLocator;
		this.conversionService = conversionService;
		initFactories(predicates);
		gatewayFilterFactories.forEach(
				factory -> this.gatewayFilterFactories.put(factory.name(), factory));
		this.gatewayProperties = gatewayProperties;
	}

调用initFactories(predicates);方法,将内置的Predicate解析成对应的
Map<String, RoutePredicateFactory> predicates 类型,存放到RouteDefinitionRouteLocator 中的成员变量predicates中,
在这里,我们可以看到,gateway源码对应每一个Predicate的定时的key是通过,
NameUtils.normalizeRoutePredicateName(getClass());
进行解析获取

public static String normalizeRoutePredicateName(
			Class<? extends RoutePredicateFactory> clazz) {
		return removeGarbage(clazz.getSimpleName()
				.replace(RoutePredicateFactory.class.getSimpleName(), ""));
	}

该方法实际上是通过替换,将每一个Predicate类的名称进行替换,例如:
HostRoutePredicateFactory 替换成Host(截取掉了RoutePredicateFactory.class.getSimpleName())信息

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐