public class RouteDefinition {
// 唯一id
private String id;
// 断言定义
private List predicates = new ArrayList<>();
// 过滤器定义
private List filters = new ArrayList<>();
// 跳转uri
private URI uri;
// 元数据
private Map
// Spring优先级
private int order = 0;
}
复制代码
断言定义PredicateDefinition
=======================
从配置文件加载的断言定义,构造Route时,会用RoutePredicateFactory#applyAsync转换成AsyncPredicate。
public class PredicateDefinition {
private String name;
private Map
public PredicateDefinition() {
}
// predicates:
// - Path=/echo // 解析’Path=/echo’放入args
public PredicateDefinition(String text) {
int eqIdx = text.indexOf(‘=’);
// 设置name
setName(text.substring(0, eqIdx));
String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), “,”);
// 设置args
for (int i = 0; i < args.length; i++) {
this.args.put(NameUtils.generateName(i), args[i]);
}
}
}
复制代码
路由过滤器定义FilterDefinition
=======================
从配置文件加载的路由过滤器定义,构造Route时,会用GatewayFilterFactory#apply转换为GatewayFilter。
public class FilterDefinition {
private String name;
private Map
public FilterDefinition() {
}
// 解析配置文件 PrefixPath=/httpbin
public FilterDefinition(String text) {
int eqIdx = text.indexOf(‘=’);
if (eqIdx <= 0) {
setName(text);
return;
}
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]);
}
}
}
复制代码
获取路由定义RouteDefinitionLocator
============================
RouteDefinitionLocator具有获取路由定义的能力。
public interface RouteDefinitionLocator {
Flux getRouteDefinitions();
}
复制代码
最后对外暴露的实际是CompositeRouteDefinitionLocator,他组合了所有RouteDefinitionLocator。
![](https://img-blog.csdnimg.cn/img_convert/b075e72cebbb8c 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 da7634379b698c2012.png)
获取路由RouteLocator
================
RouteLocator具有获取路由Route的能力。网关处理请求时只会调用RouteLocator获取Route,通过Route的断言和过滤处理请求。
public interface RouteLocator {
Flux getRoutes();
}
复制代码
Spring容器加载的时候,会把路由都放到CachingRouteLocator里,后续运行时只会和CachingRouteLocator打交道。
二、加载路由
======
讲解从Gateway的Bean装配,到加载Route到CachingRouteLocator。
自动配置
====
Spring-Cloud-Gateway的自动配置类是org.springframework.cloud.gateway.config.GatewayAutoConfiguration。重点看一些重要的Bean装配,全局Filter等下一章节讲请求流程的时候再分析。
Gateway配置文件
===========
@Bean
public GatewayProperties gatewayProperties() {
return new GatewayProperties();
}
@ConfigurationProperties(“spring.cloud.gateway”)
@Validated
public class GatewayProperties {
// 路由
private List routes = new ArrayList<>();
// 默认过滤器
private List defaultFilters = new ArrayList<>();
}
复制代码
RouteDefinitionLocator相关
========================
@Bean
@ConditionalOnMissingBean
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(
GatewayProperties properties) {
return new PropertiesRouteDefinitionLocator(properties);
}
复制代码
@Bean
@ConditionalOnMissingBean(RouteDefinitionRepository.class)
public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
return new InMemoryRouteDefinitionRepository();
}
复制代码
@Bean
@Primary
public RouteDefinitionLocator routeDefinitionLocator(
List routeDefinitionLocators) {
return new CompositeRouteDefinitionLocator(
Flux.fromIterable(routeDefinitionLocators));
}
复制代码
RouteLocator相关
==============
@Bean
public RouteLocatorBuilder routeLocatorBuilder(
ConfigurableApplicationContext context) {
return new RouteLocatorBuilder(context);
}
复制代码
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
List gatewayFilters,
List predicates,
RouteDefinitionLocator routeDefinitionLocator,
ConfigurationService configurationService) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,
gatewayFilters, properties, configurationService);
}
复制代码
@Bean
@Primary
@ConditionalOnMissingBean(name = “cachedCompositeRouteLocator”)
public RouteLocator cachedCompositeRouteLocator(List routeLocators) {
return new CachingRouteLocator(
new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
复制代码
加载路由入口类RouteRefreshListener
===========================
@Bean
public RouteRefreshListener routeRefreshListener(ApplicationEventPublisher publisher) {
return new RouteRefreshListener(publisher);
}
复制代码
加载路由到CachingRouteLocator
========================
RouteRefreshListener
====================
加载路由到RouteLocator的入口,通过Spring事件触发。
public class RouteRefreshListener implements ApplicationListener {
private final ApplicationEventPublisher publisher;
public RouteRefreshListener(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent
|| event instanceof RefreshScopeRefreshedEvent
|| event instanceof InstanceRegisteredEvent) {
reset();
}
// … 省略其他事件判断,也可能触发reset
}
// 发布RefreshRoutesEvent事件
private void reset() {
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}
}
复制代码
CachingRouteLocator
===================
CachingRouteLocator收到RefreshRoutesEvent,委托CompositeRouteLocator获取Flux放入自己的缓存cache中。
public class CachingRouteLocator implements Ordered, RouteLocator,
ApplicationListener, ApplicationEventPublisherAware {
// 写死的缓存cache的key
private static final String CACHE_KEY = “routes”;
// CompositeRouteLocator
private final RouteLocator delegate;
// Route列表
private final Flux routes;
// 缓存
private final Map
// 事件发布者
private ApplicationEventPublisher applicationEventPublisher;
public CachingRouteLocator(RouteLocator delegate) {
this.delegate = delegate;
// 这里并不会触发fetch,只有当需要routes的时候才会触发fetch,比如getRoutes()
routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class)
.onCacheMissResume(this::fetch);
}
// 委托CompositeRouteLocator获取Route并排序
private Flux fetch() {
return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);
}
// 获取Route,如果routes为空,会触发fetch
@Override
public Flux getRoutes() {
return this.routes;
}
// 清空缓存
public Flux refresh() {
this.cache.clear();
return this.routes;
}
// 接收RefreshRoutesEvent
@Override
public void onApplicationEvent(RefreshRoutesEvent event) {
try {
// 委托CompositeRouteLocator获取Route并排序
fetch()
.collect(Collectors.toList())
.subscribe(list -> Flux.fromIterable(list)
.materialize().collect(Collectors.toList()).subscribe(signals -> {
applicationEventPublisher.publishEvent(new RefreshRoutesResultEvent(this));
// 放入缓存
cache.put(CACHE_KEY, signals);
}, throwable -> handleRefreshError(throwable)));
}
catch (Throwable e) {
handleRefreshError(e);
}
}
// 发生异常发布RefreshRoutesResultEvent事件
private void handleRefreshError(Throwable throwable) {
applicationEventPublisher
.publishEvent(new RefreshRoutesResultEvent(this, throwable));
}
void handleRefresh() {
refresh();
}
@Override
public int getOrder() {
return 0;
}
@Override
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}
复制代码
CompositeRouteLocator
=====================
通过其他RouteLocator获取所有Route。
public class CompositeRouteLocator implements RouteLocator {
// 其他所有RouteLocator,除了CachingRouteLocator
private final Flux delegates;
public CompositeRouteLocator(Flux delegates) {
this.delegates = delegates;
}
@Override
public Flux getRoutes() {
return this.delegates.flatMapSequential(RouteLocator::getRoutes);
}
}
复制代码
1 编码方式获取Route
=============
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.host(“**.abc.org”).and().path(“/anything/png”)
.filters(f ->
f.prefixPath(“/httpbin”)
.addResponseHeader(“X-TestHeader”, “foobar”))
.uri(uri)
)
.build();
}
复制代码
RouteLocatorBuilder.Builder构造的RouteLocator,Bean注入的时候直接构造完成了。具体构造过程不细看了,也是利用了RoutePredicateFactory和GatewayFilterFactory。
public static class Builder {
private List
public RouteLocator build() {
return () -> Flux.fromIterable(this.routes)
.map(routeBuilder -> routeBuilder.build());
}
复制代码
2 RouteDefinitionRouteLocator
=============================
RouteDefinitionRouteLocator只负责通过RouteDefinition创建Route,委托CompositeRouteDefinitionLocator获取RouteDefinition,并通过ConfigurationService、RoutePredicateFactory、GatewayFilterFactory将RouteDefinition转换为Route返回。
public class RouteDefinitionRouteLocator
implements RouteLocator, BeanFactoryAware, ApplicationEventPublisherAware {
// 默认过滤器名字
public static final String DEFAULT_FILTERS = “defaultFilters”;
// 委托CompositeRouteDefinitionLocator
private final RouteDefinitionLocator routeDefinitionLocator;
// ConfigurationService操作RoutePredicateFactory和GatewayFilterFactory
// 转换断言和过滤器
private final ConfigurationService configurationService;
// name - RoutePredicateFactory
private final Map
// name - GatewayFilterFactory
private final Map
// spring.cloud.gateway配置文件
private final GatewayProperties gatewayProperties;
@Override
public Flux getRoutes() {
Flux routes = this.routeDefinitionLocator
// 委托CompositeRouteDefinitionLocator获取RouteDefinition
.getRouteDefinitions()
// 转换为Route
.map(this::convertToRoute);
// 如果spring.cloud.gateway.failOnRouteDefinitionError=true(默认)
// 仅仅打印日志
if (!gatewayProperties.isFailOnRouteDefinitionError()) {
routes = routes.onErrorContinue((error, obj) -> {
logger.warn(…);
});
}
return routes;
}
}
复制代码
getRouteDefinitions循环所有RouteDefinitionLocator获取所有RouteDefinition。
public class CompositeRouteDefinitionLocator implements RouteDefinitionLocator {
private final Flux delegates;
private final IdGenerator idGenerator;
public CompositeRouteDefinitionLocator(Flux delegates) {
this(delegates, new AlternativeJdkIdGenerator());
}
public CompositeRouteDefinitionLocator(Flux delegates,
IdGenerator idGenerator) {
this.delegates = delegates;
this.idGenerator = idGenerator;
}
@Override
public Flux getRouteDefinitions() {
return this.delegates
// 委托所有其他RouteDefinitionLocator获取RouteDefinition
.flatMapSequential(RouteDefinitionLocator::getRouteDefinitions)
.flatMap(routeDefinition -> {