网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览

栏目: Java · 发布时间: 8年前

内容简介:网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览

摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/route-locator-intro/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Spring-Cloud-Gateway 2.0.X M4

网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览

关注 微信公众号:【芋道源码】 有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有 源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言 将得到 认真 回复。 甚至不知道如何读源码也可以请教噢
  4. 新的 源码解析文章 实时 收到通知。 每周更新一篇左右
  5. 认真的 源码交流微信群。

1. 概述

本文主要对 路由定位器 RouteLocator 做整体的认识

《Spring-Cloud-Gateway 源码解析 —— 路由(1.1)之 RouteDefinitionLocator 一览》 中,我们对 RouteLocator 对了简单的介绍 :

  • 网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览
  • RouteLocator 可以直接 自定义 路由( org.springframework.cloud.gateway.route.Route ) ,也可以通过 RouteDefinitionRouteLocator 获取 RouteDefinition ,并转换成 Route 。
  • RoutePredicateHandlerMapping 使用 RouteLocator 获得 Route 信息。

推荐 Spring Cloud 书籍:

2. Route

org.springframework.cloud.gateway.route.Route ,路由。代码如下 :

public class Route implements Ordered{

 /**
* 路由编号
*/
 private final String id;
 /**
* 路由向的 URI
*/
 private final URI uri;
 /**
* 顺序
*/
 private final int order;
 /**
* 谓语数组
*/
 private final Predicate<ServerWebExchange> predicate;
 /**
* 过滤器数组
*/
 private final List<GatewayFilter> gatewayFilters;
}
  • id 属性,ID 编号, 唯一
  • predicates 属性,谓语数组。 请求 通过 predicates 判断是否 匹配
  • filters 属性,过滤器数组。
  • uri 属性,路由向的 URI 。
  • order 属性,顺序。当请求匹配到多个路由时,使用顺序 的。
  • 网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览

Route 内置 Builder 类,点击 链接 查看。

Route 提供 routeDefinition RouteDefinition 创建对象,代码如下 :

public static Builder builder(RouteDefinition routeDefinition){
 return new Builder()
 .id(routeDefinition.getId())
 .uri(routeDefinition.getUri())
 .order(routeDefinition.getOrder());
}
  • predicate / gatewayFilters 属性,需要调用 Builder 相关方法进行设置。

3. RouteLocator

org.springframework.cloud.gateway.route.RouteLocator ,路由定位器 接口 ,定义获得路由数组的方法。代码如下 :

public interface RouteLocator{

 Flux<Route> getRoutes();

}
  • 对 Reactor Flux 暂时不熟悉的同学,可以阅读完本文 Google 进行学习。随着 Spring 5 对响应式编程的推广,厉害如你一定要去掌握。

在上文中,我们也看到了 RouteLocator 的多个实现类,类图如下 :

网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览

  • 本文只解析 CompositeRouteLocator / CachingRouteLocator 的源码实现。其他的实现类会在后面文章详细解析。
  • 自定义的 RouteLocator ,通过 内部类 实现,类图暂时不好体现。

4. CompositeRouteLocator

org.springframework.cloud.gateway.route.CompositeRouteLocator ,组合 多种 RouteLocator 的实现类,为 RoutePredicateHandlerMapping 提供 统一 入口访问路由。代码如下 :

public class CompositeRouteLocator implements RouteLocator{

 private final Flux<RouteLocator> delegates;

 public CompositeRouteLocator(Flux<RouteLocator> delegates){
 this.delegates = delegates;
 }

 @Override
 public Flux<Route> getRoutes(){
 return this.delegates.flatMap(RouteLocator::getRoutes);
 }
}
  • #getRoutes() 方法,提供 统一 方法,将组合的 delegates 的路由 全部 返回。

5. CachingRouteLocator

org.springframework.cloud.gateway.route.CachingRouteLocator缓存 路由的 RouteLocator 实现类。RoutePredicateHandlerMapping 调用 CachingRouteLocator 的 RouteLocator#getRoutes() 方法,获取路由。

CachingRouteLocator 代码如下 :

public class CachingRouteLocator implements RouteLocator{

 private final RouteLocator delegate;
 /**
* 路由缓存
*/
 private final AtomicReference<List<Route>> cachedRoutes = new AtomicReference<>();

 public CachingRouteLocator(RouteLocator delegate){
 this.delegate = delegate;
 this.cachedRoutes.compareAndSet(null, collectRoutes());
 }

 @Override
 public Flux<Route> getRoutes(){
 return Flux.fromIterable(this.cachedRoutes.get());
 }

 /**
* Sets the new routes
* @return old routes
*/
 public Flux<Route> refresh(){
 return Flux.fromIterable(this.cachedRoutes.getAndUpdate(
 routes -> CachingRouteLocator.this.collectRoutes()));
 }

 private List<Route> collectRoutes(){
 List<Route> routes = this.delegate.getRoutes().collectList().block();
 // 排序
 AnnotationAwareOrderComparator.sort(routes);
 return routes;
 }

 @EventListener(RefreshRoutesEvent.class)
 /* for testing */ void handleRefresh(){
 refresh();
 }
}
  • cachedRoutes 属性,路由 缓存
  • CachingRouteLocator 构造 方法,调用 #collectRoutes() 方法获得路由,并缓存到 cachedRoutes 属性。
  • #collectRoutes() 方法,从 delegate 获取路由数组。
  • #getRoutes() 方法,返回路由 缓存
  • #refresh() 方法,刷新 缓存 cachedRoutes 属性。
  • #handleRefresh() 方法,监听 org.springframework.context.ApplicationEvent.RefreshRoutesEvent 事件,刷新 缓存

GatewayWebfluxEndpoint 有 一个 HTTP API 调用了 ApplicationEventPublisher ,发布 RefreshRoutesEvent 事件。代码如下 :

@RestController
@RequestMapping("${management.context-path:/application}/gateway")
public class GatewayWebfluxEndpoint implements ApplicationEventPublisherAware{

 // ... 省略其他代码
 
 /**
* 应用事件发布器
*/
 private ApplicationEventPublisher publisher;
 
 @PostMapping("/refresh")
 public Mono<Void> refresh(){
 this.publisher.publishEvent(new RefreshRoutesEvent(this));
 return Mono.empty();
 }

}
  • POST "/refresh ,发布 RefreshRoutesEvent 事件。CachingRouteLocator 监听到该事件,刷新缓存。

666. 彩蛋

又是比较干爽( 水更 )的一篇文章。

网关 Spring-Cloud-Gateway 源码解析 —— 路由(2.1)之 RouteLocator 一览

胖友,分享一波朋友圈可好!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高性能JavaScript

高性能JavaScript

【美】Nicholas C. Zakas(尼古拉斯.泽卡斯) / 丁琛 / 电子工业出版社 / 2015-8-1 / 65

如果你使用 JavaScript 构建交互丰富的 Web 应用,那么 JavaScript 代码可能是造成你的Web应用速度变慢的主要原因。《高性能JavaScript》揭示的技术和策略能帮助你在开发过程中消除性能瓶颈。你将会了解如何提升各方面的性能,包括代码的加载、运行、DOM 交互、页面生存周期等。雅虎的前端工程师 Nicholas C. Zakas 和其他五位 JavaScript 专家介绍......一起来看看 《高性能JavaScript》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具