接口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();
}
- 根据配置获取AsyncPredicate。
- 处理当前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);
}
- 通过具体的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);
}
}
接口GatewayPredicate
继承该接口,其定义了父接口不同方法功能对应的实现类。- GatewayPredicate没有真正实现接口中方法功能。
- 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));
}
}
}
-
将2.1.1.1步骤中GatewayPredicate赋值给AsyncPredicate delegate 属性。
-
代理对象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;
}
- 获取针对全部路由的默认全局过滤器DefaultFilters。
- 获取针对某个路由下定制化过滤器Filters。
- 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();
});
});
}
- GatewayAutoConfiguration默认生成30种类型GatewayFilterFactory。
- 每个GatewayFilterFactory都会有对应的匿名内部类GatewayFilter。
- 真正过滤功能是在请求流转过程中会回调匿名内部类的处理逻辑。
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;
}