日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Cloud Gateway 源码解析(2) —— 路由

發布時間:2024/4/13 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Cloud Gateway 源码解析(2) —— 路由 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

基本組件

路由定位器(RouteDefinitionLocator?)

路由定義(RouteDefinition)

?PredicateDefinition

FilterDefinition

CompositeRouteDefinitionLocator

路由定位器 (RouteLocator)

Route

?

RouteDefinitionLocator解析

PropertiesRouteDefinitionLocator?

GatewayProperties

RouteDefinitionRepository?

RouteDefinitionWriter?

InMemoryRouteDefinitionRepository

自定義RouteDefinitionRepository

DiscoveryClientRouteDefinitionLocator?

RouteLocator解析

RouteLocator

CompositeRouteLocator

CachingRouteLocator

RouteDefinitionRouteLocator?

構造函數

獲得 Route

自定義 RouteLocator


基本組件

路由定位器(RouteDefinitionLocator?)

RouteDefinitionLocator?負責讀取路由配置(RouteDefinition?),Gateway實現了多種Locator。

public interface RouteDefinitionLocator {Flux<RouteDefinition> getRouteDefinitions(); }

  • ?PropertiesRouteDefinitionLocator

從配置文件( 例如,YML / Properties 等 ) 讀取

  • RouteDefinitionRepository

從存儲器( 例如,內存 / Redis / MySQL 等 )讀取。

  • DiscoveryClientRouteDefinitionLocator

從注冊中心( 例如,Eureka / Consul / Zookeeper / Etcd 等 )讀取。

  • CompositeRouteDefinitionLocator

組合多種 RouteDefinitionLocator 的實現,為 RouteDefinitionRouteLocator 提供統一入口。

  • CachingRouteDefinitionLocator

已經被 CachingRouteLocator 取代。
? ? ??

路由定義(RouteDefinition)

@Validated public class RouteDefinition {@NotEmptyprivate String id = UUID.randomUUID().toString();@NotEmpty@Validprivate List<PredicateDefinition> predicates = new ArrayList<>();@Validprivate List<FilterDefinition> filters = new ArrayList<>();@NotNullprivate URI uri;private int order = 0; }
  • id?屬性,ID 編號,唯一
  • predicates?屬性,謂語定義數組。請求通過?predicates?判斷是否匹配。在 Route 里,PredicateDefinition 轉換成 Predicate 。
  • filters?屬性,過濾器定義數組。在 Route 里,FilterDefinition 轉換成 GatewayFilter 。
  • uri?屬性,路由向的 URI 。
  • order?屬性,順序。當請求匹配到多個路由時,使用順序的。

RouteDefinition 提供?text?字符串創建對象(yaml配置中屬性值),格式為:

${id}=${uri},${predicates[0]},${predicates[1]}...${predicates[n]}

public RouteDefinition(String text) ;

?PredicateDefinition

@Validated public class PredicateDefinition {/*** 謂語定義名字,通過 name 對應到 org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory 的實現類*/@NotNullprivate String name;/*** 參數數組*/private Map<String, String> args = new LinkedHashMap<>(); }

提供了構造函數:

/*** 根據 text 創建 PredicateDefinition** @param text 格式 ${name}=${args[0]},${args[1]}...${args[n]}* 例如 Host=iocoder.cn*/ public PredicateDefinition(String text);

FilterDefinition

@Validated public class FilterDefinition {/*** 過濾器定義名字。通過 name 對應到 org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory 的實現類*/@NotNullprivate String name;/*** 參數數組*/private Map<String, String> args = new LinkedHashMap<>(); }

提供了構造函數:

/*** 根據 text 創建 FilterDefinition** @param text 格式 ${name}=${args[0]},${args[1]}...${args[n]}* 例如 AddRequestParameter=foo, bar*/ public FilterDefinition(String text);

CompositeRouteDefinitionLocator

組合多種?RouteDefinitionLocator 的實現,為 RouteDefinitionRouteLocator 提供統一入口

@Overridepublic Flux<RouteDefinition> getRouteDefinitions() {return this.delegates.flatMap(RouteDefinitionLocator::getRouteDefinitions).flatMap(routeDefinition -> {if (routeDefinition.getId() == null) {return randomId().map(id -> {routeDefinition.setId(id);if (log.isDebugEnabled()) {log.debug("Id set on route definition: " + routeDefinition);}return routeDefinition;});}return Mono.just(routeDefinition);});}

路由定位器 (RouteLocator)

  • RouteLocator 可以直接自定義路由(?org.springframework.cloud.gateway.route.Route?) ,也可以通過 RouteDefinitionRouteLocator 獲取 RouteDefinition ,并轉換成 Route 。
  • RoutePredicateHandlerMapping 使用 RouteLocator 獲得 Route 信息。

Route

Route與RouteDefinition結構相似。同時實現了Order接口。

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

Route 內置 Builder 類,根據RouteDefinition 構造對象。predicate?/?gatewayFilters?屬性,需要調用 Builder 相關方法進行設置

public static Builder builder(RouteDefinition routeDefinition) {// @formatter:offreturn new Builder().id(routeDefinition.getId()).uri(routeDefinition.getUri()).order(routeDefinition.getOrder()).metadata(routeDefinition.getMetadata());// @formatter:on}

?

RouteDefinitionLocator解析

PropertiesRouteDefinitionLocator?

GatewayProperties 中獲取路由信息。

public class PropertiesRouteDefinitionLocator implements RouteDefinitionLocator {private final GatewayProperties properties;public PropertiesRouteDefinitionLocator(GatewayProperties properties) {this.properties = properties;}@Overridepublic Flux<RouteDefinition> getRouteDefinitions() {return Flux.fromIterable(this.properties.getRoutes());}}

GatewayProperties

GatewayProperties?,從配置文件讀取?:

  • 路由配置

通過?spring.cloud.gateway.routes?配置

  • 默認過濾器配置。當 RouteDefinition => Route 時,會將過濾器配置添加到每個?Route 。

通過?spring.cloud.gateway.default-filters?配置

@ConfigurationProperties("spring.cloud.gateway") @Validated public class GatewayProperties {/*** List of Routes.*/@NotNull@Validprivate List<RouteDefinition> routes = new ArrayList<>();/*** List of filter definitions that are applied to every route.*/private List<FilterDefinition> defaultFilters = new ArrayList<>(); }

RouteDefinitionRepository?

public interface RouteDefinitionRepositoryextends RouteDefinitionLocator, RouteDefinitionWriter {}

類繼承關系如下:?

RouteDefinitionWriter?

RouteDefinitionWriter?,路由配置寫入接口。該接口定義了保存刪除兩個方法

public interface RouteDefinitionWriter {/*** 保存路由配置** @param route 路由配置* @return Mono<Void>*/Mono<Void> save(Mono<RouteDefinition> route);/*** 刪除路由配置** @param routeId 路由編號* @return Mono<Void>*/Mono<Void> delete(Mono<String> routeId); }

InMemoryRouteDefinitionRepository

基于內存為存儲器的 RouteDefinitionLocator

public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {private final Map<String, RouteDefinition> routes = synchronizedMap(new LinkedHashMap<String, RouteDefinition>());@Overridepublic Flux<RouteDefinition> getRouteDefinitions() {return Flux.fromIterable(routes.values());} }

路由信息構造:

@Overridepublic Mono<Void> save(Mono<RouteDefinition> route) {return route.flatMap(r -> {if (StringUtils.isEmpty(r.getId())) {return Mono.error(new IllegalArgumentException("id may not be empty"));}routes.put(r.getId(), r);return Mono.empty();});}@Overridepublic Mono<Void> delete(Mono<String> routeId) {return routeId.flatMap(id -> {if (routes.containsKey(id)) {routes.remove(id);return Mono.empty();}return Mono.defer(() -> Mono.error(new NotFoundException("RouteDefinition not found: " + routeId)));});}

自定義RouteDefinitionRepository

可以自定義RouteDefinitionRepository,如果沒有自定義,才使用內存存儲。

// GatewayAutoConfiguration.java @Bean @ConditionalOnMissingBean(RouteDefinitionRepository.class) public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {return new InMemoryRouteDefinitionRepository(); }

DiscoveryClientRouteDefinitionLocator?

DiscoveryClientRouteDefinitionLocator 通過調用?org.springframework.cloud.client.discovery.DiscoveryClient?獲取注冊在注冊中心的服務列表,生成對應的 RouteDefinition 數組。

public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLocator {private final DiscoveryLocatorProperties properties;private final String routeIdPrefix;private final SimpleEvaluationContext evalCtxt;private Flux<List<ServiceInstance>> serviceInstances;}

@Overridepublic Flux<RouteDefinition> getRouteDefinitions() {SpelExpressionParser parser = new SpelExpressionParser();Expression includeExpr = parser.parseExpression(properties.getIncludeExpression());Expression urlExpr = parser.parseExpression(properties.getUrlExpression());//構造服務實例是否可用predicate。Predicate<ServiceInstance> includePredicate;if (properties.getIncludeExpression() == null|| "true".equalsIgnoreCase(properties.getIncludeExpression())) {includePredicate = instance -> true;}else {includePredicate = instance -> {Boolean include = includeExpr.getValue(evalCtxt, instance, Boolean.class);if (include == null) {return false;}return include;};}return serviceInstances.filter(instances -> !instances.isEmpty())//返回可用實例.map(instances -> instances.get(0)).filter(includePredicate).map(instance -> { //構建definitionRouteDefinition routeDefinition = buildRouteDefinition(urlExpr,instance);final ServiceInstance instanceForEval = new DelegatingServiceInstance(instance, properties); //拷貝PredicateDefinition for (PredicateDefinition original : this.properties.getPredicates()) {PredicateDefinition predicate = new PredicateDefinition();predicate.setName(original.getName());for (Map.Entry<String, String> entry : original.getArgs().entrySet()) { //計算表達式值。String value = getValueFromExpr(evalCtxt, parser,instanceForEval, entry);predicate.addArg(entry.getKey(), value);}routeDefinition.getPredicates().add(predicate);} //拷貝FilterDefinition for (FilterDefinition original : this.properties.getFilters()) {FilterDefinition filter = new FilterDefinition();filter.setName(original.getName());for (Map.Entry<String, String> entry : original.getArgs().entrySet()) { //計算表達式值。String value = getValueFromExpr(evalCtxt, parser,instanceForEval, entry);filter.addArg(entry.getKey(), value);}routeDefinition.getFilters().add(filter);}return routeDefinition;});}

RouteLocator解析

RouteLocator

路由定位器接口,定義獲得路由數組的方法

public interface RouteLocator {Flux<Route> getRoutes(); }

CompositeRouteLocator

組合多種?RouteLocator 的實現類,為 RoutePredicateHandlerMapping 提供統一入口訪問路由

public class CompositeRouteLocator implements RouteLocator {private final Flux<RouteLocator> delegates;public CompositeRouteLocator(Flux<RouteLocator> delegates) {this.delegates = delegates;}@Overridepublic Flux<Route> getRoutes() {return this.delegates.flatMap(RouteLocator::getRoutes);}}

CachingRouteLocator

CachingRouteLocator?,緩存路由的 RouteLocator 實現類。RoutePredicateHandlerMapping 調用 CachingRouteLocator 的?RouteLocator#getRoutes()?方法,獲取路由。

public class CachingRouteLocatorimplements Ordered, RouteLocator, ApplicationListener<RefreshRoutesEvent> {private static final String CACHE_KEY = "routes";private final RouteLocator delegate;private final Flux<Route> routes;private final Map<String, List> cache = new ConcurrentHashMap<>();public CachingRouteLocator(RouteLocator delegate) {this.delegate = delegate;routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class).onCacheMissResume(this::fetch);} }

RouteDefinitionRouteLocator?

RouteDefinitionRouteLocator?,基于?RouteDefinitionLocator?的 RouteLocator?實現類。RouteDefinitionRouteLocator 從 RouteDefinitionLocator 獲取 RouteDefinition ,轉換成 Route?

public class RouteDefinitionRouteLocatorimplements RouteLocator, BeanFactoryAware, ApplicationEventPublisherAware {/*** Default filters name.*/public static final String DEFAULT_FILTERS = "defaultFilters";protected final Log logger = LogFactory.getLog(getClass());private final RouteDefinitionLocator routeDefinitionLocator;private final ConfigurationService configurationService;private final Map<String, RoutePredicateFactory> predicates = new LinkedHashMap<>();private final Map<String, GatewayFilterFactory> gatewayFilterFactories = new HashMap<>();private final GatewayProperties gatewayProperties; }

構造函數

public RouteDefinitionRouteLocator(RouteDefinitionLocator routeDefinitionLocator,List<RoutePredicateFactory> predicates,List<GatewayFilterFactory> gatewayFilterFactories,GatewayProperties gatewayProperties,ConfigurationService configurationService) {this.routeDefinitionLocator = routeDefinitionLocator;this.configurationService = configurationService;initFactories(predicates);gatewayFilterFactories.forEach(factory -> this.gatewayFilterFactories.put(factory.name(), factory));this.gatewayProperties = gatewayProperties;}

獲得 Route

@Overridepublic Flux<Route> getRoutes() {//routeDefinitionLocator獲取RouteDefinitions,轉換成RouteFlux<Route> routes = this.routeDefinitionLocator.getRouteDefinitions().map(this::convertToRoute);//錯誤是否拋出異常if (!gatewayProperties.isFailOnRouteDefinitionError()) {// instead of letting error bubble up, continueroutes = routes.onErrorContinue((error, obj) -> {if (logger.isWarnEnabled()) {logger.warn("RouteDefinition id " + ((RouteDefinition) obj).getId()+ " will be ignored. Definition has invalid configs, "+ error.getMessage());}});}return routes.map(route -> {if (logger.isDebugEnabled()) {logger.debug("RouteDefinition matched: " + route.getId());}return route;});}//合并predicate,合并filters,構造一個route。private Route convertToRoute(RouteDefinition routeDefinition) {AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);return Route.async(routeDefinition).asyncPredicate(predicate).replaceFilters(gatewayFilters).build();}

自定義 RouteLocator

RouteLocatorBuilder用于自定義RouteLocator

public class RouteLocatorBuilder { public Builder routes() {return new Builder(context);} } public static class Builder {private List<Route.AsyncBuilder> routes = new ArrayList<>();private ConfigurableApplicationContext context;public Builder(ConfigurableApplicationContext context) {this.context = context;} }
  • RouteSpec:route builder。
  • UriSpec:可以添加一個Uri
  • PredicateSpec:可以應用到一個Uri的Predicate。
  • BooleanOpSpec:邏輯操作Predicate。
  • GatewayFilterSpec:GatewayFilter

?

總結

以上是生活随笔為你收集整理的Spring Cloud Gateway 源码解析(2) —— 路由的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。