2、SpringCloud之Gateway断言Predicate&GatewayFilterFactory源码解析

接口RouteLocator:实现类包括CachingRouteLocator、CompositeRouteLocator、RouteDefinitionRouteLocator。

接口RouteDefinitionLocator:CacheRouteDefinitionLocator、CompositeRouteDefinitionLocator、InMemoryRouteDefinitionRepository、PropertiesRouteDefinitionLocator、接口RouteDefinitionLocatorRepository、DiscoveryClientRouteDefinitionLocator。

接口RoutePredicateFactory:默认生成14种路由策略。PathRoutePredicateFactory、HeaderRoutePredicateFactory等。

接口Predicate:

1、GatewayAutoConfiguration

初始化13种路由策略、30种GatewayFilter、RouteDefinitionRouteLocator。

2、RouteDefinitionRouteLocator

public class RouteDefinitionRouteLocator
		implements RouteLocator, BeanFactoryAware, ApplicationEventPublisherAware {
		
	private final Map<String, RoutePredicateFactory> predicates = new LinkedHashMap<>();
	private final Map<String, GatewayFilterFactory> gatewayFilterFactories = new HashMap<>();
	
	public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,
			List<RoutePredicateFactory> predicates,List<GatewayFilterFactory> gatewayFilterFactories,
			GatewayProperties gatewayProperties,ConfigurationService configurationService) {
		// CompositeRouteDefinitionLocator
		this.routeDefinitionLocator = routeDefinitionLocator;
		this.configurationService = configurationService;
		//13种路由策略
		initFactories(predicates);
		// 30种GatewayFilter
		gatewayFilterFactories.forEach(
		// GatewayFilterFactory factory.name():获取实现类基于接口的前缀
				factory -> this.gatewayFilterFactories.put(factory.name(), factory));
		this.gatewayProperties = gatewayProperties;
	}
}
private void initFactories(List<RoutePredicateFactory> predicates) {
	predicates.forEach(factory -> {
		String key = factory.name();//获取实现类基于接口的前缀
		this.predicates.put(key, factory);
	});
}

匹配规则与其对应的实体对象建立映射关系。

RoutePredicateFactory的全部实现类名是在其接口RoutePredicateFactory增加了“策略”前缀。比如PathRoutePredicateFactory表明请求基于“前缀Path”路径的匹配规则。HostRoutePredicateFactory表明请求基于“前缀host”host匹配指定值等。

private Route convertToRoute(RouteDefinition routeDefinition) {
	AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
	List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);
	return Route.async(routeDefinition).asyncPredicate(predicate)
			.replaceFilters(gatewayFilters).build();
}
  1. 根据配置获取AsyncPredicate。
  2. 处理当前Routes下的过滤器。

备注:GatewayProperties中规定routes选项可以配置多个不同目标服务的路由Route。convertToRoute只是处理其中某个Route对应的RouteDefinition。

private AsyncPredicate<ServerWebExchange> combinePredicates(
		RouteDefinition routeDefinition) {
	List<PredicateDefinition> predicates = routeDefinition.getPredicates();
	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;
}
private AsyncPredicate<ServerWebExchange> lookup(RouteDefinition route,
		PredicateDefinition predicate) {
	// 根据配置文件从RouteDefinitionRouteLocator属性集合中获取对应的Predicate
	RoutePredicateFactory<Object> factory = this.predicates.get(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
	//jdk8中接口默认方法,PathRoutePredicateFactory
	return factory.applyAsync(config);
}
  1. 通过具体的RoutePredicateFactory接口实现类获取AsyncPredicate。

2.1、初始化predicate策略

以RoutePredicateFactory接口的实现类PathRoutePredicateFactory为分析对象,如下:

default AsyncPredicate<ServerWebExchange> applyAsync(C config) {
	return toAsyncPredicate(apply(config));
}

PathRoutePredicateFactory#apply方法主要功能:创建匿名内部类GatewayPredicate,并实现其接口Predicate中test路由匹配功能。

public static AsyncPredicate<ServerWebExchange> toAsyncPredicate(
		Predicate<? super ServerWebExchange> predicate) {
	return AsyncPredicate.from(predicate);
}

2.1.1、Predicate接口

public interface Predicate<T> {
	boolean test(T t);//Evaluates this predicate on the given argument.
	default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
}
  1. 接口GatewayPredicate继承该接口,其定义了父接口不同方法功能对应的实现类。
  2. GatewayPredicate没有真正实现接口中方法功能。
  3. GatewayPredicate作为RoutePredicateFactory接口匿名内部类实现了路由匹配的策略。
2.1.2、接口AsyncPredicate
public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {

	static AsyncPredicate<ServerWebExchange> from(Predicate<? super ServerWebExchange> predicate) {
		return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
	}
	class DefaultAsyncPredicate<T> implements AsyncPredicate<T> {
		private final Predicate<T> delegate;
		public DefaultAsyncPredicate(Predicate<T> delegate) {
			this.delegate = delegate;
		}
		@Override
		public Publisher<Boolean> apply(T t) {
			// 实时匹配路径
			return Mono.just(delegate.test(t));
		}
	}
}
  1. 将2.1.1.1步骤中GatewayPredicate赋值给AsyncPredicate delegate 属性。

  2. 代理对象GatewayPredicate真正实现了路由匹配功能。

    请求流转时路径实时匹配

2.2、GatewayFilter

private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
	List<GatewayFilter> filters = new ArrayList<>();
	//配置文件中defaultFilters策略,针对全部route的全局过滤策略
	if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
		// RequestRateLimiter为例
		filters.addAll(loadGatewayFilters(DEFAULT_FILTERS,
				this.gatewayProperties.getDefaultFilters()));
	}
	
	if (!routeDefinition.getFilters().isEmpty()) {
		filters.addAll(loadGatewayFilters(routeDefinition.getId(),
				routeDefinition.getFilters()));
	}

	AnnotationAwareOrderComparator.sort(filters);
	return filters;
}
  1. 获取针对全部路由的默认全局过滤器DefaultFilters。
  2. 获取针对某个路由下定制化过滤器Filters。
  3. GatewayFilterFactory是用来创建接口GatewayFilter的匿名内部类。

2.2.1、GatewayFilterFactory

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);
		//根据FilterDefinition中name属性【配置文件映射获取】从默认30种GatewayFilter中获取对应的RequestRateLimiterGatewayFilterFactory工厂类
		GatewayFilterFactory factory = this.gatewayFilterFactories
				.get(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();
		if (configuration instanceof HasRouteId) {
			HasRouteId hasRouteId = (HasRouteId) configuration;
			hasRouteId.setRouteId(id);
		}
		// RequestRateLimiterGatewayFilterFactory
		GatewayFilter gatewayFilter = factory.apply(configuration);
		if (gatewayFilter instanceof Ordered) {
			ordered.add(gatewayFilter);
		}
		else {
			ordered.add(new OrderedGatewayFilter(gatewayFilter, i + 1));
		}
	}
	return ordered;
}

2.2.2、GatewayFilter

RequestRateLimiterGatewayFilterFactory#apply:创建匿名内部类过滤器GatewayFilter。【非调用】

public GatewayFilter apply(Config config) {
	KeyResolver resolver = getOrDefault(config.keyResolver, defaultKeyResolver);
	RateLimiter<Object> limiter = getOrDefault(config.rateLimiter,
			defaultRateLimiter);
	boolean denyEmpty = getOrDefault(config.denyEmptyKey, this.denyEmptyKey);
	HttpStatusHolder emptyKeyStatus = HttpStatusHolder
			.parse(getOrDefault(config.emptyKeyStatus, this.emptyKeyStatusCode));
	// 创建接口GatewayFilter的匿名实现类
	// 以下也是真正限流逻辑
	return (exchange, chain) -> resolver.resolve(exchange).defaultIfEmpty(EMPTY_KEY)
			.flatMap(key -> {
				if (EMPTY_KEY.equals(key)) {
					if (denyEmpty) {
						setResponseStatus(exchange, emptyKeyStatus);
						return exchange.getResponse().setComplete();
					}
					return chain.filter(exchange);
				}
				String routeId = config.getRouteId();
				if (routeId == null) {
					Route route = exchange
							.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
					routeId = route.getId();
				}
				return limiter.isAllowed(routeId, key).flatMap(response -> {
					for (Map.Entry<String, String> header : response.getHeaders()
							.entrySet()) {
						exchange.getResponse().getHeaders().add(header.getKey(),
								header.getValue());
					}
					if (response.isAllowed()) {
						return chain.filter(exchange);
					}
					setResponseStatus(exchange, config.getStatusCode());
					return exchange.getResponse().setComplete();
				});
			});
}
  1. GatewayAutoConfiguration默认生成30种类型GatewayFilterFactory。
  2. 每个GatewayFilterFactory都会有对应的匿名内部类GatewayFilter。
  3. 真正过滤功能是在请求流转过程中会回调匿名内部类的处理逻辑。

2.3、Route

public class Route implements Ordered {

	private final String id;
	private final URI uri;
	private final int order;
	private final AsyncPredicate<ServerWebExchange> predicate;
	private final List<GatewayFilter> gatewayFilters;
}	

3、解析RouteDefinition

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值