精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringCloud Gateway 路由如何定位從底層源碼分析

開發 前端
所有的謂詞工廠繼承的AbstractRoutePredicateFactory中的泛型都是內部類的Config。這個是如何被配置上值的呢?

環境:springcloud Hoxton.SR11

本節主要了解系統中的謂詞與配置的路由信息是如何進行初始化關聯生成路由對象的。每個謂詞工廠中的Config對象又是如何被解析配置的。

所有的謂詞工廠中的Config中屬性值是如何被配置的。

在SpringCloud Gateway中的所有謂詞工廠如下:

圖片圖片

命名規則:XxxRoutePredicateFactory。所有的這些謂詞工廠都是如下的繼承關系

public class MethodRoutePredicateFactory extends   AbstractRoutePredicateFactory<MethodRoutePredicateFactory.Config>
// 
public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config>
// ...

所有的謂詞工廠繼承的AbstractRoutePredicateFactory中的泛型都是內部類的Config。這個是如何被配置上值的呢?

1.1 gateway自動配置

在下面這個類中配置了所有的Predicate和Filter。

public class GatewayAutoConfiguration {
  @Bean
  @ConditionalOnEnabledPredicate
  public PathRoutePredicateFactory pathRoutePredicateFactory() {
    return new PathRoutePredicateFactory();
  }
  @Bean
  @ConditionalOnEnabledPredicate
  public QueryRoutePredicateFactory queryRoutePredicateFactory() {
    return new QueryRoutePredicateFactory();
  }
  @Bean
  public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties, List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> predicates, RouteDefinitionLocator routeDefinitionLocator, ConfigurationService configurationService) {
    return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,
            gatewayFilters, properties, configurationService);
  }
  @Bean
  @Primary
  @ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
  public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
    return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
  }
}

這里會層層委托最終查找查找路由定位會交給RouteDefinitionRouteLocator。CachingRouteLocator起到緩存的作用,將配置的所有路由信息保存。

注意:這里的路由信息是在容器啟動后就會被初始化的。

public class CachingRouteLocator {
  private final RouteLocator delegate;


  private final Flux<Route> routes;


  private final Map<String, List> cache = new ConcurrentHashMap<>();


  private ApplicationEventPublisher applicationEventPublisher;


  public CachingRouteLocator(RouteLocator delegate) {
    this.delegate = delegate;
    routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class) .onCacheMissResume(this::fetch);
  }


  private Flux<Route> fetch() {
    return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);
  }
}

實例化CachingRouteLocator就開始查找所有配置的Route信息。最終的會委托給RouteDefinitionRouteLocator

RouteDefinitionRouteLocator構造函數中的initFactories方法用來映射路由工廠的XxxRoutePredicateFactory。

private void initFactories(List<RoutePredicateFactory> predicates) {
  predicates.forEach(factory -> {
    String key = factory.name();
    if (this.predicates.containsKey(key)) {
      this.logger.warn("A RoutePredicateFactory named " + key + " already exists, class: " + this.predicates.get(key) + ". It will be overwritten.");
    }
    this.predicates.put(key, factory);
  });
}

方法中解析每一個謂詞工廠對應的名稱然后緩存到predicates 集合中。

factory.name()方法解析謂詞名稱。

default String name() {
  return NameUtils.normalizeRoutePredicateName(getClass());
}

CachingRouteLocator是個緩存路由定位器,是個首選的RouteLocator(@Primary),這里將RouteDefinitionRouteLocator進行了合并。

1.2 生成路由對象Route及Config配置

getRoutes---》convertToRoute---》combinePredicates---》lookup。

根據上面的自動配置也知道了在服務啟動時就進行初始化所有路由信息了。

獲取路由信息

public Flux<Route> getRoutes() {
  Flux<Route> routes = this.routeDefinitionLocator.getRouteDefinitions() .map(this::convertToRoute);
  routes = routes.onErrorContinue((error, obj) -> {
    return routes.map(route -> {
            return route;
  });
}

合并謂詞(鏈式調用)

private AsyncPredicate<ServerWebExchange> combinePredicates(
            RouteDefinition routeDefinition) {
  // other code
  for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
    AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
    predicate = predicate.and(found);
  }
  return predicate;
}

進入lookup中

private AsyncPredicate<ServerWebExchange> lookup(RouteDefinition route, PredicateDefinition predicate) {
  RoutePredicateFactory<Object> factory = this.predicates.get(predicate.getName());
  if (factory == null) {
    throw new IllegalArgumentException("Unable to find RoutePredicateFactory with name " + predicate.getName());
  }
  // 這里將配置中(yml文件)配置的name,args和謂詞工廠中的Config進行關聯設置值
  Object config = this.configurationService.with(factory)
    .name(predicate.getName())
    .properties(predicate.getArgs())
    .eventFunction((bound, properties) -> new PredicateArgsEvent(
        RouteDefinitionRouteLocator.this, route.getId(), properties))
    .bind();
  // 最終調用謂詞工廠(XxxRoutePredicateFactory的apply方法返回RoutePredicate該對象繼承Predicate)
  return factory.applyAsync(config);
}

lookup方法中查找,也就是在這里將對應的謂詞Config與RouteDefinition(Predicate)中定義的相對應的屬性關聯。

進入factory.applyAsync方法

@FunctionalInterface
public interface RoutePredicateFactory<C> extends ShortcutConfigurable, Configurable<C> {
  default AsyncPredicate<ServerWebExchange> applyAsync(C config) {
    return toAsyncPredicate(apply(config)); // 查看下面的6.2-1圖當前apply所有的實現就是系統內部定義的XxxRoutePredicateFactory
  }
}
// apply(config),如這里配置了Path謂詞,那么就會進入PathRoutePredicateFactory中的apply方法
public Predicate<ServerWebExchange> apply(Config config) {
  // other code    
  return new GatewayPredicate() {
    public boolean test() {
      // todo    
    }
  }
}
// 最后返回一個異步的謂詞
public static AsyncPredicate<ServerWebExchange> toAsyncPredicate(Predicate<? super ServerWebExchange> predicate) {
  Assert.notNull(predicate, "predicate must not be null");
  // 這里from就是返回一個DefaultAsyncPredicate默認的異步謂詞
  return AsyncPredicate.from(predicate);
}
static AsyncPredicate<ServerWebExchange> from( Predicate<? super ServerWebExchange> predicate) {
  return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
}

圖6.2-1

圖片圖片

最后在combinePredicates方法中將當前路由中配置的所有謂詞進行了and操作返回。最終回到convertToRoute方法中將當前路由中配置的謂詞,過濾器進行了整合包裝返回Route(一個路由對象)

public class Route implements Ordered {
  private final String id;
   
  private final URI uri;
   
  private final int order;
   
  private final AsyncPredicate<ServerWebExchange> predicate;
   
  private final List<GatewayFilter> gatewayFilters;
   
  private final Map<String, Object> metadata;
}

這些Route對象會被保存在上面說的
CachingRouteLocator.routes中。

6.3 定位路由

根據上面的配置RouteLocator 該類用來定位路由(查找具體的使用哪個路由);當一個請求過來會查找是哪個路由。

RouteLocator中定義了一個方法

public interface RouteLocator {


  Flux<Route> getRoutes();


}

查看這個getRoutes方法是誰調用的

圖片圖片

看到這個RoutePredicateHandlerMapping是不是想起了Spring MVC中的HandlerMapping(我們所有的Controller都會被 RequestMappingHanlderMapping 匹配)。通過名稱也就知道了該HandlerMapping用來匹配我們的路由謂詞的誰來處理路由。

接下來回到前面說的RequestMappingHanlderMapping 對象,當我們請求一個路由地址時會執行該類中的lookup方法查找路由

protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
  // 這里的this.routeLocator就是 CachingRouteLocator對象 
  return this.routeLocator.getRoutes()
      .concatMap(route -> Mono.just(route).filterWhen(r -> {
        exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
        // 過濾查找符合的路由  
        return r.getPredicate().apply(exchange);
     }).doOnError(e -> logger.error(
          "Error applying predicate for route: " + route.getId(),
     e)).onErrorResume(e -> Mono.empty()))
        .next()
        .map(route -> {
          if (logger.isDebugEnabled()) {
            logger.debug("Route matched: " + route.getId());
          }
          validateRoute(route, exchange);
          return route;
     });
}

進入r.getPredicate().apply(exchange)

public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
  static AsyncPredicate<ServerWebExchange> from(Predicate<? super ServerWebExchange> predicate) {
  return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
  }


  class DefaultAsyncPredicate<T> implements AsyncPredicate<T> {


    private final Predicate<T> delegate;


    public DefaultAsyncPredicate(Predicate<T> delegate) {
      this.delegate = delegate;
    }


    @Override
    public Publisher<Boolean> apply(T t) {
      return Mono.just(delegate.test(t));
    }


    @Override
    public String toString() {
      return this.delegate.toString();
    }


  }


}

這里會調用Predicate.test方法(XxxRoutePredicateFactory中的apply方法返回的GatewayPredicate)。

調用GatewayPredicate.test返回判斷當前請求的路由是否匹配。

整體的一個流程:

1、系統先初始化所有的Predicate(謂詞)和Filter(過濾器)

2、根據配置的路由信息(過濾器,謂詞)包裝返回Route對象

3、根據請求路由路徑查找匹配的路由


責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2021-07-07 06:38:33

SpringCloud路由配置定位原理分析

2023-07-20 10:04:37

底層路由配置

2021-03-26 22:23:13

Python算法底層

2021-07-20 10:26:53

源碼底層ArrayList

2019-10-16 16:33:41

Docker架構語言

2021-03-26 06:01:45

日志MongoDB存儲

2023-03-17 17:51:30

APIServer路由注冊

2025-03-05 00:49:00

Win32源碼malloc

2020-12-14 08:03:52

ArrayList面試源碼

2020-12-17 08:03:57

LinkedList面試源碼

2010-07-29 08:41:11

路由器故障

2010-08-10 11:19:28

路由器故障

2020-04-27 07:13:37

Nginx底層進程

2023-11-09 09:08:38

RibbonSpring

2022-05-12 08:21:13

項目網關模塊

2022-06-12 07:27:39

微服務GateWay

2023-07-17 08:02:44

ZuulIO反應式

2022-05-16 08:22:11

網關過濾器路由

2025-03-31 00:00:00

MCPAPI服務器通信

2024-01-29 08:00:00

架構微服務開發
點贊
收藏

51CTO技術棧公眾號

www.成人| 激情一区二区三区| 一级国产黄色片| 国产精品13p| 国产日韩欧美在线一区| 成人久久一区二区| 国产精品白浆一区二小说| 自拍亚洲一区| 日韩欧美国产一区在线观看| koreanbj精品视频一区| 国产黄色片在线观看| 国产精品自拍一区| 日韩暖暖在线视频| 成年人午夜剧场| 亚洲性视频大全| 欧美一区二区视频网站| 欧美 日韩精品| 91国内在线| 国产日产欧美一区二区视频| 国产在线拍偷自揄拍精品| 国产一卡二卡在线播放| 青青一区二区三区| 日韩精品中文字| 一卡二卡三卡四卡五卡| xxxxx.日韩| 图片区日韩欧美亚洲| 99亚洲精品视频| 精品资源在线看| 成年人网站91| 亚洲精品免费一区二区三区| 国产精品免费无遮挡无码永久视频| 亚洲网色网站| 在线播放精品一区二区三区| 一级黄色免费视频| 成人午夜在线| 在线亚洲一区二区| 免费看又黄又无码的网站| 麻豆影院在线观看| 国产欧美一区二区精品婷婷 | 亚洲电影一二三区| 三级网站免费观看| 国产成人精品一区二区三区四区 | 国产亚洲va综合人人澡精品 | 无码h黄肉3d动漫在线观看| 久久国产人妖系列| 国产精品美女免费看| 国产黄色免费观看| 9色精品在线| 高清欧美性猛交xxxx| 九九热只有精品| 综合精品久久| 欧美另类在线观看| 我要看黄色一级片| 91久久高清国语自产拍| 日韩一级黄色av| 99久久99久久精品免费看小说.| 亚洲亚洲免费| 亚洲偷欧美偷国内偷| 性少妇bbw张开| 国产欧美高清视频在线| 亚洲美女自拍视频| 亚洲天堂久久新| 精品国产一区二区三区噜噜噜 | 亚洲白拍色综合图区| 动漫av在线免费观看| 8x国产一区二区三区精品推荐| 91精品国产入口在线| 免费欧美一级片| aaa国产精品视频| 亚洲第一精品福利| 短视频在线观看| 九九热精品视频在线观看| 亚洲天堂日韩电影| 青青青视频在线播放| 91一区二区| 欧美另类第一页| 日韩少妇高潮抽搐| 视频一区二区中文字幕| 国产精品免费一区二区三区都可以| 少妇又紧又色又爽又刺激视频| 久久精品国产成人一区二区三区| 国产在线高清精品| 亚洲精品成av人片天堂无码| 99久久免费国产| 日本一区二区三区视频在线观看 | 四季av一区二区三区免费观看| 久久深夜福利免费观看| 免费一级特黄特色大片| 男女精品视频| 成人性生交大片免费看视频直播 | 欧美视频免费看欧美视频| 欧美激情网站| 欧美日韩中字一区| 制服.丝袜.亚洲.中文.综合懂| 盗摄牛牛av影视一区二区| 亚洲美女黄色片| 可以免费看av的网址| 亚洲五月婷婷| 国产精品男女猛烈高潮激情| 精品人妻一区二区三区含羞草| 成人高清在线视频| 亚洲高清资源综合久久精品| 精品精品导航| 欧美日精品一区视频| 性高潮免费视频| 日韩电影免费在线观看| 久久久日本电影| 中文字幕一二区| 97精品久久久久中文字幕| 亚洲图片欧洲图片日韩av| 都市激情久久综合| 欧美日韩黄色影视| 91av在线免费| 午夜精品偷拍| 国产精品三级久久久久久电影| 成人毛片在线精品国产| 国产精品成人免费在线| 免费看国产一级片| vam成人资源在线观看| 亚洲免费成人av电影| 久久久久人妻一区精品色欧美| 日本不卡一区二区| 久久99久久精品国产| 三级资源在线| 欧美日韩成人在线一区| 亚洲男人在线天堂| 海角社区69精品视频| 91精品免费看| 91xxx在线观看| 欧美日韩亚洲一区二| 精品久久久久久无码人妻| 日韩精品2区| 国产成+人+综合+亚洲欧洲| 日韩一级中文字幕| 一区二区三区四区视频精品免费| 爱爱爱爱免费视频| 超碰成人久久| 26uuu国产精品视频| 成人午夜视频一区二区播放| 亚洲免费在线观看视频| 亚洲美女性囗交| 日本久久综合| 国产精品成人免费视频| 欧美女同网站| 91久久人澡人人添人人爽欧美| 国产精品九九视频| 亚洲大片在线| 国产麻豆一区二区三区在线观看| av在线下载| 欧美一卡2卡三卡4卡5免费| 日本少妇aaa| 久久国产剧场电影| 综合操久久久| 免费精品一区| 欧美国产日韩一区| 国产黄色av网站| 亚洲一区二区四区蜜桃| 亚洲成a人无码| 韩国欧美一区| 精品视频在线观看| 在线毛片观看| 亚洲视频第一页| 在线不卡免费视频| 国产精品大尺度| 妖精视频在线观看| 国内自拍一区| 欧美视频1区| yy6080久久伦理一区二区| 久久精品2019中文字幕| 国产高清视频免费| 亚洲午夜精品在线| 亚洲欧美色图视频| 日韩电影在线免费| 少妇熟女一区二区| 综合中文字幕| 欧美综合激情网| 不卡在线视频| 欧美一级午夜免费电影| 国产情侣在线视频| 国产亚洲成av人在线观看导航| 亚洲一区精品视频在线观看| 欧美激情1区2区3区| 国产一区二区三区四区hd| jk漫画禁漫成人入口| 在线看福利67194| 国产免费黄色片| 午夜影视日本亚洲欧洲精品| 色哟哟精品观看| 国产一区美女在线| 青青草国产精品视频| 精品国产91| 成人国产1314www色视频| 亚洲三级欧美| 精品国产欧美成人夜夜嗨| 日本黄色一区二区三区| 欧美午夜精品电影| 免费视频一二三区| 国产亚洲精品资源在线26u| 韩国三级与黑人| 三级亚洲高清视频| 中文字幕色呦呦| 免费欧美视频| 超碰97在线人人| 日韩毛片一区| 性欧美在线看片a免费观看| lutube成人福利在线观看| 精品久久久久99| 中文字幕一区二区三区四区视频 | 国产免费视频传媒| 欧美特黄一级| 一区二区三区四区五区视频| 清纯唯美亚洲经典中文字幕| 亚洲精品日产aⅴ| 精品3atv在线视频| 欧美激情国产高清| 毛片网站在线免费观看| 亚洲色图校园春色| 午夜视频福利在线| 日韩欧美精品在线视频| 亚洲欧美日韩一区二区三区四区| 亚洲一区二区精品3399| 999精品在线视频| 国产肉丝袜一区二区| 一区二区三区少妇| 成人免费观看视频| 美女又黄又免费的视频| 蜜桃视频在线一区| 亚洲爆乳无码专区| 99精品视频免费观看视频| 第九区2中文字幕| 天天影视天天精品| 亚洲国产一区二区精品视频 | 无码日韩精品一区二区| 亚洲v精品v日韩v欧美v专区 | 色一区在线观看| 日本一级黄色录像| 亚洲国产裸拍裸体视频在线观看乱了| 爱爱视频免费在线观看| 中文字幕在线不卡| 久草福利资源在线| 国产精品拍天天在线| 东方伊人免费在线观看| 国产亚洲一区二区三区在线观看 | 日本精品免费观看| 天堂中文在线播放| 欧美综合在线观看| 伊伊综合在线| 国产精品www| 日韩三区免费| 国产精品电影观看| 国产精品美女午夜爽爽| 成人观看高清在线观看免费| 国产精品毛片无码| 亚洲综合视频1区| 婷婷视频一区二区三区| 97se亚洲综合| silk一区二区三区精品视频| 成人资源视频网站免费| 爱爱精品视频| 玛丽玛丽电影原版免费观看1977| 天天久久夜夜| 欧洲精品一区色| jiujiure精品视频播放| 亚洲一区二区高清视频| **女人18毛片一区二区| 日本a在线天堂| 亚洲精品影视| 国产又黄又猛视频| 久久se精品一区精品二区| 国产精品999.| 99视频热这里只有精品免费| 90岁老太婆乱淫| 亚洲国产高清不卡| 91视频免费在线看| 午夜国产不卡在线观看视频| 伊人中文字幕在线观看 | 性少妇videosexfreexxx片| 精品欧美久久久| 九色在线观看| 欧美成年人在线观看| 黄色aa久久| 国产精品久久久久久久久免费| 五月天色综合| 国产精品一区二区三区不卡| 农村少妇一区二区三区四区五区| 日韩欧美亚洲区| 国产综合婷婷| 激情综合网俺也去| 国产**成人网毛片九色| 国产女主播喷水高潮网红在线| 国产精品麻豆久久久| 国产成人啪精品午夜在线观看| 色婷婷久久99综合精品jk白丝| 国产精品免费无遮挡| 亚洲精品国产免费| av成人手机在线| 久久久久久免费精品| 日本国产欧美| 国产精品一区而去| 日韩欧美视频| 欧美国产激情视频| 国产精品一区二区x88av| www.超碰97| 亚洲黄色在线视频| 青青艹在线观看| 精品国产123| 国产一二三区在线观看| 日韩av理论片| 国产精品久久久久av蜜臀| 一区二区三区四区国产| 国产精品美女久久久| 欧美性猛交xx| 国产精品久久久久久久岛一牛影视| 国产特黄大片aaaa毛片| 欧美一二三在线| 成人在线播放视频| 欧美亚洲国产日本| 亚洲视频三区| 妞干网这里只有精品| 美腿丝袜在线亚洲一区| 国产制服丝袜在线| 亚洲午夜一二三区视频| 国产黄色一区二区| 视频在线一区二区| 欧美不卡高清一区二区三区| 黑人巨大精品欧美一区二区小视频 | 日韩欧美高清一区| 九色porny在线| 国产欧美精品在线| 精品国产美女| 国产精品人人妻人人爽人人牛| 不卡高清视频专区| 精品少妇theporn| 91精品国产综合久久久蜜臀粉嫩| 国产黄色片在线观看| 国产成人久久久精品一区| 色愁久久久久久| 欧美在线观看www| 99在线精品免费| 欧美成人午夜激情在线| 精品毛片在线观看| 俺去啦;欧美日韩| 色综合视频一区二区三区日韩| 日韩国产在线一区| 青青草国产成人av片免费| 久久精品无码一区| 欧美午夜精品久久久久久超碰| 福利片在线看| 国产日韩在线看片| 97久久夜色精品国产| 五月六月丁香婷婷| 亚洲日本在线视频观看| 国产福利视频导航| 久久久久久av| 日本一区福利在线| 激情五月亚洲色图| 亚洲国产高清在线观看视频| 91精品视频免费在线观看| 久久久国产一区二区| 免费看日产一区二区三区| 日韩国产小视频| 99在线热播精品免费| 久久久久久不卡| 深夜精品寂寞黄网站在线观看| 经典三级久久| 人妻av中文系列| 91免费精品国自产拍在线不卡| 在线永久看片免费的视频| 最新亚洲国产精品| 日韩精品一级| jizzjizzxxxx| 中文字幕 久热精品 视频在线| 一本到在线视频| 久久久久久久久久久久久久久久久久av| 国产精品网在线观看| 麻豆av免费在线| 亚洲人午夜精品天堂一二香蕉| 亚洲第一大网站| 国产v综合v亚洲欧美久久| 国产精品久久观看| 99精品一区二区三区无码吞精| 欧美性xxxxhd| 国产网站在线免费观看| 国产精品一区在线播放| 日韩av在线播放中文字幕| 精品人妻伦九区久久aaa片| 亚洲精品美女免费| 国产精品亲子伦av一区二区三区| 无码熟妇人妻av在线电影| 久久久久久久精| www男人的天堂| 日韩av手机在线| 午夜日韩在线| 中文字幕免费高清| 欧美白人最猛性xxxxx69交| 国产 日韩 欧美一区| 成人在线国产视频| 欧美国产精品v| 色丁香婷婷综合久久| 国产欧美日韩中文字幕在线|