SpringCloudGateway源码阅读(一)核心概念及路由加载

public class RouteDefinition {

// 唯一id

private String id;

// 断言定义

private List predicates = new ArrayList<>();

// 过滤器定义

private List filters = new ArrayList<>();

// 跳转uri

private URI uri;

// 元数据

private Map metadata = new HashMap<>();

// Spring优先级

private int order = 0;

}

复制代码

断言定义PredicateDefinition

=======================

从配置文件加载的断言定义,构造Route时,会用RoutePredicateFactory#applyAsync转换成AsyncPredicate。

public class PredicateDefinition {

private String name;

private Map args = new LinkedHashMap<>();

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 args = new LinkedHashMap<>();

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打交道。

SpringCloudGateway源码阅读(一)核心概念及路由加载_第1张图片

二、加载路由

======

讲解从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相关

========================

  • PropertiesRouteDefinitionLocator:配置文件创建RouteDefinitionLocator

@Bean

@ConditionalOnMissingBean

public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(

GatewayProperties properties) {

return new PropertiesRouteDefinitionLocator(properties);

}

复制代码

  • InMemoryRouteDefinitionRepository:内存级别路由定义,无法持久化,支持动态新增和删除路由定义

@Bean

@ConditionalOnMissingBean(RouteDefinitionRepository.class)

public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {

return new InMemoryRouteDefinitionRepository();

}

复制代码

  • CompositeRouteDefinitionLocator:组合其他所有的RouteDefinitionLocator,并且是Primary的

@Bean

@Primary

public RouteDefinitionLocator routeDefinitionLocator(

List routeDefinitionLocators) {

return new CompositeRouteDefinitionLocator(

Flux.fromIterable(routeDefinitionLocators));

}

复制代码

RouteLocator相关

==============

  • RouteLocatorBuilder:辅助用编码方式注入自定义的RouteLocator。

@Bean

public RouteLocatorBuilder routeLocatorBuilder(

ConfigurableApplicationContext context) {

return new RouteLocatorBuilder(context);

}

复制代码

  • RouteDefinitionRouteLocator:用RouteDefinitionLocator和GatewayFilterFactory和RoutePredicateFactory构造Route,创建RouteLocator。

@Bean

public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,

List gatewayFilters,

List predicates,

RouteDefinitionLocator routeDefinitionLocator,

ConfigurationService configurationService) {

return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,

gatewayFilters, properties, configurationService);

}

复制代码

  • CachingRouteLocator:委托CompositeRouteLocator聚合其他所有RouteLocator,实现RouteLocator。

@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

========================

SpringCloudGateway源码阅读(一)核心概念及路由加载_第2张图片

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 cache = new ConcurrentHashMap<>();

// 事件发布者

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 routes = new ArrayList<>();

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 predicates = new LinkedHashMap<>();

// name - GatewayFilterFactory

private final Map gatewayFilterFactories = new HashMap<>();

// 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;

}

}

复制代码

  • CompositeRouteDefinitionLocator

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 -> {

你可能感兴趣的:(Java,经验分享,架构,java)