Spring Cloud Gateway——路由分析

概述

Spring Cloud Gateway的路由裏包含了API的轉發邏輯、處理切面,是Spring Cloud Gateway最最關鍵的組件。在Spring Cloud Gateway裏有兩種添加路由的方式:一種是properties配置方式,一種是Java代碼配置方式。
一起看下,Spring Cloud Gateway路由配置信息轉化成路由對象,並且和RoutePredicateHandlerMapping建立關聯關係的過程。

路由初始化

在這裏插入圖片描述
Spring Cloud Gateway的路由延續了Spring一貫的做法,由RouteDefinition和Route兩個基礎類組成,RouteDefinition對應到properties文件中的路由描述,Route對應爲路由的內存數據結構。

RouteDefinitionLocator實現RouteDefinition的查找、解析,當前Spring Cloud Gateway支持3種形式的路由描述存儲方式,也就是上圖綠色的1,2,3:PropertiesRouteDefinitionLocator(properties文件)、DiscoveryClientRouteDefinitionLocator(服務發現)、InMemoryRouteDefinitionRepository(內存存儲,用於動態路由)。

CompositeRouteDefinitionLocator是一個合成器,集合裏上述3個路由,並且被註解爲了@Primary,所以路由定義解析的時候都會從CompositeRouteDefinitionLocator裏獲取路由描述,也就是能同時取出PropertiesRouteDefinitionLocator、DiscoveryClientRouteDefinitionLocator、InMemoryRouteDefinitionRepository
3種形式存儲的路由描述。

builder.routes().build()返回的是一個RouteLocator類型的實例,和CompositeRouteDefinitionLocator一樣,都會注入到CompositeRouteLocator裏,再封裝成CachingRouteLocator。

RoutePredicationHandlerMapping在處理webflux請求的時候,逐個調用RouteLocator中所有Route實例的Predicte.apply方法確定此次請求由哪個Route處理。

RouteDefinitionRouteLocator

RouteDefinitionRouteLocator用來把RouteDefinition轉換成Route,轉換過程在convertToRoute方法完成。

private Route convertToRoute(RouteDefinition routeDefinition) {
		//1.解析predicate
		AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
		//2.解析filters
		List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);
		//3.構建Route對象實例
		return Route.async(routeDefinition).asyncPredicate(predicate)
				.replaceFilters(gatewayFilters).build();
	}

Predicate和GatewayFilter的解析邏輯類似,都是通過Definition.name()找到對應的解析Factory,然後完成Definition到對象實例的解析過程。
以下是PredicteFactory的內置實現:
在這裏插入圖片描述
以下是GatewayFilter的內置實現:
在這裏插入圖片描述

builder.routes().route(fn).build()

buidler是一個RouteLocatorBuilder類型的實例,在GatewayAutoConfiguration裏創建。
builder.route()創建一個內部類的實例,也就是RouteLocatorBuilder.Builder的實例,用來構建Route對象。

.route(fn)用來創建routeBuilder,並且添加到RouteLocatorBuilder.Builder的routes列表裏。
fn是一個FunctionalInterface接口,入參是PredicateSpec,返回值是Route.AsyncBuilder。

		public Builder route(Function<PredicateSpec, Route.AsyncBuilder> fn) {
			//fn的入參是一個RouteSpec對象
			Route.AsyncBuilder routeBuilder = fn.apply(new RouteSpec(this).randomId());
			//添加到routes列表
			add(routeBuilder);
			return this;
		}

.build()返回一個RouteLocator,內部邏輯是逐個創建Route對象。

		public RouteLocator build() {
			return () -> Flux.fromIterable(this.routes)
					.map(routeBuilder -> routeBuilder.build());
		}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章