欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Cloud Gateway之校验断言(Predicate)

程序员文章站 2022-03-15 13:11:48
...

文章目录


1 介绍

spring cloud gateway源码中,内置了大量的Predicate工具,用于处理不同情况下的断言信息,
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())信息

相关标签: Spring源码