环境:springcloud Hoxton.SR11


(资料图片)

本节主要了解系统中的谓词与配置的路由信息是如何进行初始化关联生成路由对象的。每个谓词工厂中的Config对象又是如何被解析配置的。

所有的谓词工厂中的Config中属性值是如何被配置的。

在SpringCloud Gateway中的所有谓词工厂如下:

图片

命名规则:XxxRoutePredicateFactory。所有的这些谓词工厂都是如下的继承关系

public class MethodRoutePredicateFactory extends   AbstractRoutePredicateFactory// public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory// ...

所有的谓词工厂继承的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 gatewayFilters, List predicates, RouteDefinitionLocator routeDefinitionLocator, ConfigurationService configurationService) {    return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,            gatewayFilters, properties, configurationService);  }  @Bean  @Primary  @ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")  public RouteLocator cachedCompositeRouteLocator(List routeLocators) {    return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));  }}

这里会层层委托最终查找查找路由定位会交给RouteDefinitionRouteLocator。CachingRouteLocator起到缓存的作用,将配置的所有路由信息保存。

注意:这里的路由信息是在容器启动后就会被初始化的。

public class CachingRouteLocator {  private final RouteLocator delegate;  private final Flux routes;  private final Map 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 fetch() {    return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);  }}

实例化CachingRouteLocator就开始查找所有配置的Route信息。最终的会委托给RouteDefinitionRouteLocator

RouteDefinitionRouteLocator构造函数中的initFactories方法用来映射路由工厂的XxxRoutePredicateFactory。

private void initFactories(List 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 getRoutes() {  Flux routes = this.routeDefinitionLocator.getRouteDefinitions() .map(this::convertToRoute);  routes = routes.onErrorContinue((error, obj) -> {    return routes.map(route -> {            return route;  });}

合并谓词(链式调用)

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

进入lookup中

private AsyncPredicate lookup(RouteDefinition route, PredicateDefinition predicate) {  RoutePredicateFactory 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方法

@FunctionalInterfacepublic interface RoutePredicateFactory extends ShortcutConfigurable, Configurable {  default AsyncPredicate applyAsync(C config) {    return toAsyncPredicate(apply(config)); // 查看下面的6.2-1图当前apply所有的实现就是系统内部定义的XxxRoutePredicateFactory  }}// apply(config),如这里配置了Path谓词,那么就会进入PathRoutePredicateFactory中的apply方法public Predicate apply(Config config) {  // other code      return new GatewayPredicate() {    public boolean test() {      // todo        }  }}// 最后返回一个异步的谓词public static AsyncPredicate toAsyncPredicate(Predicate predicate) {  Assert.notNull(predicate, "predicate must not be null");  // 这里from就是返回一个DefaultAsyncPredicate默认的异步谓词  return AsyncPredicate.from(predicate);}static AsyncPredicate from( Predicate 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 predicate;     private final List gatewayFilters;     private final Map metadata;}

这些Route对象会被保存在上面说的CachingRouteLocator.routes中。

6.3 定位路由

根据上面的配置RouteLocator 该类用来定位路由(查找具体的使用哪个路由);当一个请求过来会查找是哪个路由。

RouteLocator中定义了一个方法

public interface RouteLocator {  Flux getRoutes();}

查看这个getRoutes方法是谁调用的

图片

看到这个RoutePredicateHandlerMapping是不是想起了Spring MVC中的HandlerMapping(我们所有的Controller都会被 RequestMappingHanlderMapping 匹配)。通过名称也就知道了该HandlerMapping用来匹配我们的路由谓词的谁来处理路由。

接下来回到前面说的RequestMappingHanlderMapping 对象,当我们请求一个路由地址时会执行该类中的lookup方法查找路由

protected Mono 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 extends Function> {  static AsyncPredicate from(Predicate predicate) {  return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));  }  class DefaultAsyncPredicate implements AsyncPredicate {    private final Predicate delegate;    public DefaultAsyncPredicate(Predicate delegate) {      this.delegate = delegate;    }    @Override    public Publisher 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、根据请求路由路径查找匹配的路由

推荐内容

  • SpringCloud Gateway 路由如何定位从底层源码分析
    SpringCloud Gateway 路由如何定位从底层源码分析

  • 石家庄雍禾种植毛发医院正规吗 医院地址 实力推荐
    石家庄雍禾种植毛发医院正规吗 医院地址 实力推荐

  • 湖北利川:青山绿水 风光无限
    湖北利川:青山绿水 风光无限

  • “兰恩”升级为强台风 预计于15日接近日本东、西部地区
    “兰恩”升级为强台风 预计于15日接近日本东、西部地区

  • 第三批出境团队游名单公布 同程旅行签证咨询量涨近3倍
    第三批出境团队游名单公布 同程旅行签证咨询量涨近3倍

  • 上半年西藏交通运输厅累计落实中央投资逾410亿元
    上半年西藏交通运输厅累计落实中央投资逾410亿元

  • 7月四川居民消费价格同比下降0.4% 环比上涨0.4%
    7月四川居民消费价格同比下降0.4% 环比上涨0.4%

  • 八月煤价将震荡偏弱运行
    八月煤价将震荡偏弱运行

  • 1-7月广东外贸出口再上新台阶突破3万亿元
    1-7月广东外贸出口再上新台阶突破3万亿元

  • 斗罗大陆:五位女神登场集结后宫争艳,小舞温柔的灵魂让人动容
    斗罗大陆:五位女神登场集结后宫争艳,小舞温柔的灵魂让人动容

  • 抢市场、冲销量,8 月车市再起降价潮
    抢市场、冲销量,8 月车市再起降价潮

  • 王导:黄金持续下跌,反弹1922接着空!
    王导:黄金持续下跌,反弹1922接着空!

  • 河北此次洪涝灾害因灾死亡29人 16人失联
    河北此次洪涝灾害因灾死亡29人 16人失联

  • 法拉利表示:超25%中国买家为女性
    法拉利表示:超25%中国买家为女性

  • 专精特新企业审核有绿色通道?广东省工业和信息化厅:防范不良中介机构!
    专精特新企业审核有绿色通道?广东省工业和信息化厅:防范不良中介机构!

  • 箭牌家居(001322):8月11日北向资金减持17万股
    箭牌家居(001322):8月11日北向资金减持17万股

  • 唐大军:抢抓机遇 乘势而上 高水平建设西部陆海新通道重庆主枢纽
    唐大军:抢抓机遇 乘势而上 高水平建设西部陆海新通道重庆主枢纽

  • 李旦梅到东安调研科技创新工作
    李旦梅到东安调研科技创新工作

  • 艾迪药业:8月10日融资买入36.56万元,融资融券余额1.09亿元
    艾迪药业:8月10日融资买入36.56万元,融资融券余额1.09亿元

  • 【独家】起底境外势力
    【独家】起底境外势力

  • 中信建投:这次会出现价值搭台成长唱戏吗?
    中信建投:这次会出现价值搭台成长唱戏吗?

  • 暑期公益课堂陪伴孩子快乐成长
    暑期公益课堂陪伴孩子快乐成长

  • 体育运动意外保险多少钱?如何投保?
    体育运动意外保险多少钱?如何投保?

  • 全国农技中心印发大豆促壮株、强群体、催鼓粒肥水管理技术指导意见
    全国农技中心印发大豆促壮株、强群体、催鼓粒肥水管理技术指导意见

  • 联合国秘书长对尼日尔总统及其家人的恶劣生存条件深表关切
    联合国秘书长对尼日尔总统及其家人的恶劣生存条件深表关切

  • 江苏南京落地3万吨/年报废动力电池回收利用项目
    江苏南京落地3万吨/年报废动力电池回收利用项目

  • 光格科技:8月10日融券卖出3.44万股,融资融券余额4132.73万元
    光格科技:8月10日融券卖出3.44万股,融资融券余额4132.73万元

  • 记者:热那亚租借尤文中卫德温特,包含有条件的强制买断条款
    记者:热那亚租借尤文中卫德温特,包含有条件的强制买断条款

  • 智翔金泰:8月10日融券卖出4168股,融资融券余额5325.22万元
    智翔金泰:8月10日融券卖出4168股,融资融券余额5325.22万元

  • “马上回家看望母亲,这是命令”
    “马上回家看望母亲,这是命令”

  • 全省工业设备上云率全国第一
    全省工业设备上云率全国第一

  • 膨化食品抽检报告:大肠菌群最高超标5000倍以上;部分知名品牌多次出现不合格
    膨化食品抽检报告:大肠菌群最高超标5000倍以上;部分知名品牌多次出现不合格

  • 广州江南颐养苑收费价格表
    广州江南颐养苑收费价格表

  • 双飞燕推出第三代光轴机械键盘:按键寿命达1亿次
    双飞燕推出第三代光轴机械键盘:按键寿命达1亿次

  • 加拿大罢工事件告一段落 纸浆期货回归基本面
    加拿大罢工事件告一段落 纸浆期货回归基本面

  • 山东德州市平原县发生5.5级地震
    山东德州市平原县发生5.5级地震

  • 乌克兰首都基辅在拉响防空警报后响起多次爆炸声
    乌克兰首都基辅在拉响防空警报后响起多次爆炸声

  • 焦点访谈丨向险而行,挺进“孤岛”
    焦点访谈丨向险而行,挺进“孤岛”

  • 大连活动策划公司-大连舞台搭建布置
    大连活动策划公司-大连舞台搭建布置

  • 杭州夫妻投靠落户条件(婚龄+住所+居住证)
    杭州夫妻投靠落户条件(婚龄+住所+居住证)

  • 再见恩比德!史诗5方交易方案诞生,快船得到哈登
    再见恩比德!史诗5方交易方案诞生,快船得到哈登

  • “篮球之城”东莞燃起夏日战火!石碣“村BA”激情开打!
    “篮球之城”东莞燃起夏日战火!石碣“村BA”激情开打!

  • 2023国际冬季运动(北京)博览会将在首钢园区举办
    2023国际冬季运动(北京)博览会将在首钢园区举办

  • 检验部队应急救援能力 武警湖南总队某部开展抢险救援演练
    检验部队应急救援能力 武警湖南总队某部开展抢险救援演练

  • 股东大笔增持超亿元!这些中报翻倍股成热点
    股东大笔增持超亿元!这些中报翻倍股成热点

  • 自贡沿滩区王井镇:打造城乡治理专业化人才队伍
    自贡沿滩区王井镇:打造城乡治理专业化人才队伍

  • 商水:农商银行员工拾金不昧获赠锦旗
    商水:农商银行员工拾金不昧获赠锦旗

  • 上交所:尽快制定互联互通下开通大宗交易(非自动对盘交易)实施方案
    上交所:尽快制定互联互通下开通大宗交易(非自动对盘交易)实施方案

  • “看起来很美”的夏令营为何被屡屡吐槽 揭秘内部运营“潜规则”
    “看起来很美”的夏令营为何被屡屡吐槽 揭秘内部运营“潜规则”

  • 新西兰食品价格自2022年初以来首次下跌 央行加息压力缓解
    新西兰食品价格自2022年初以来首次下跌 央行加息压力缓解

  • 隆华新材:公司CASE用聚醚及正在建设的端氨基聚醚可用于上述领域,感谢您的关注与分享!
    隆华新材:公司CASE用聚醚及正在建设的端氨基聚醚可用于上述领域,感谢您的关注与分享!

  • 幸亏过路女司机凌晨多看了两眼 网友:疲劳驾驶很危险
    幸亏过路女司机凌晨多看了两眼 网友:疲劳驾驶很危险

  • 四川:上半年超15万辆新能源汽车享受车购税政策减免
    四川:上半年超15万辆新能源汽车享受车购税政策减免

  • 跟着“钢七连”,再一次热血出征
    跟着“钢七连”,再一次热血出征

  • 民国是国号吗,民国算中国吗
    民国是国号吗,民国算中国吗

  • 灯塔专业版发布数据,演出行业暑期档票房为23.27亿元
    灯塔专业版发布数据,演出行业暑期档票房为23.27亿元

  • CF嘉年华CFM币商城兑换方法
    CF嘉年华CFM币商城兑换方法

  • 【财经分析】MSCI中国季度调整新增29只剔除19只 关注对部分个股潜在冲击
    【财经分析】MSCI中国季度调整新增29只剔除19只 关注对部分个股潜在冲击

  • 限时免费看电影!正义未曾缺席 《暴裂无声 (2017)》5天限免
    限时免费看电影!正义未曾缺席 《暴裂无声 (2017)》5天限免

  • 河北本次特大暴雨过程降雨量达275亿立方米 最大点位累计降雨量达1008.5毫米
    河北本次特大暴雨过程降雨量达275亿立方米 最大点位累计降雨量达1008.5毫米

  • 西共体放话要军事干涉后,五角大楼表态了……
    西共体放话要军事干涉后,五角大楼表态了……

  • 直播回放|世界大象日,一起去看云南野生动物
    直播回放|世界大象日,一起去看云南野生动物

  • 西安交警莲湖大队多措并举保障辖区市场周边秩序
    西安交警莲湖大队多措并举保障辖区市场周边秩序

  • 深圳艺星隆鼻好吗?医院整形技术靠谱/资质正规放心入手、价格也可一看
    深圳艺星隆鼻好吗?医院整形技术靠谱/资质正规放心入手、价格也可一看

  • 公告速递:信诚货币基金暂停代销渠道大额申购、大额转换转入、大额定期定额投资业务
    公告速递:信诚货币基金暂停代销渠道大额申购、大额转换转入、大额定期定额投资业务

  • 彩虹集团:截至2023年8月10日,公司股东总户数21,626户(合并普通账户和融资融券信用账户)
    彩虹集团:截至2023年8月10日,公司股东总户数21,626户(合并普通账户和融资融券信用账户)

  • 黑龙江粮食部门全面清理粮库排水系统 确保粮食储存安全
    黑龙江粮食部门全面清理粮库排水系统 确保粮食储存安全

  • 国星光电(002449.SZ):会继续推进国星半导体引入战略投资者事宜
    国星光电(002449.SZ):会继续推进国星半导体引入战略投资者事宜

  • 密歇根大学开发出新EV专利技术 可用于汽车防盗
    密歇根大学开发出新EV专利技术 可用于汽车防盗

  • 春秋战国时期第一个称王的是哪个诸侯
    春秋战国时期第一个称王的是哪个诸侯

  • MAX科技园(青岛·红湾)推动产业服务最大化 引领企业办公新潮流
    MAX科技园(青岛·红湾)推动产业服务最大化 引领企业办公新潮流

  • 2023-24赛季法甲前瞻:大巴黎剑指卫冕,南特恐难逃降级
    2023-24赛季法甲前瞻:大巴黎剑指卫冕,南特恐难逃降级

  • 科举考试阅卷如何进行评分?
    科举考试阅卷如何进行评分?

  • 白粉虱虫害防治最佳方法 蔬菜易发白粉虱
    白粉虱虫害防治最佳方法 蔬菜易发白粉虱

  • 焦点访谈丨向险而行 挺进“孤岛”
    焦点访谈丨向险而行 挺进“孤岛”

  • 光明地产完成发行6亿元中票 利率确定为3.0%
    光明地产完成发行6亿元中票 利率确定为3.0%

  • 华能四川公司圆满完成大运会保供任务
    华能四川公司圆满完成大运会保供任务

  • 今日黄金技术走势分析:黄金接近跌破1910美元 美联储“9月加息恐慌”来袭
    今日黄金技术走势分析:黄金接近跌破1910美元 美联储“9月加息恐慌”来袭

  • 摩根大通:维持中国联通“中性”评级 目标价6.7港元
    摩根大通:维持中国联通“中性”评级 目标价6.7港元

  • 日本宫城县近海海域发生4.7级地震
    日本宫城县近海海域发生4.7级地震

  • 湖南出台措施稳定和促进就业 惠企减负 发放补贴 鼓励创业
    湖南出台措施稳定和促进就业 惠企减负 发放补贴 鼓励创业

  • 俄发射“月球-25”号探测器,重启中止47年的探月任务
    俄发射“月球-25”号探测器,重启中止47年的探月任务

  • 8月14日早高峰莘庄、佘山等9座地铁站计划限流
    8月14日早高峰莘庄、佘山等9座地铁站计划限流

  • 装备制造业后市场服务行业快速发展,数智化升级势在必行
    装备制造业后市场服务行业快速发展,数智化升级势在必行

  • 9图了解猴痘病毒防护科普
    9图了解猴痘病毒防护科普

  • 中央网信办印发《网站平台受理处置涉企网络侵权信息举报工作规范》
    中央网信办印发《网站平台受理处置涉企网络侵权信息举报工作规范》

  • 三大指数均跌逾1% 证券板块跌近4%
    三大指数均跌逾1% 证券板块跌近4%

  • 福建:“四大经济”省级高层次人才可获财政奖补
    福建:“四大经济”省级高层次人才可获财政奖补

  • 最高检依法对易鹏飞决定逮捕
    最高检依法对易鹏飞决定逮捕

  • 记者在河北涿州一线探访——生产生活秩序正在有序恢复
    记者在河北涿州一线探访——生产生活秩序正在有序恢复

  • 成都:可授权公积金中心每月将提取金额直接划转用于支付房租
    成都:可授权公积金中心每月将提取金额直接划转用于支付房租

  • 浙江各市接连召开市委全会,为何都聚焦这4个字?
    浙江各市接连召开市委全会,为何都聚焦这4个字?

  • 天风证券:调高康缘药业机构评级为“买入”,目标价为24.72元
    天风证券:调高康缘药业机构评级为“买入”,目标价为24.72元

  • 悲伤逆流成河小说齐铭结局写的两行字是啥 悲伤逆流成河齐铭喜欢谁
    悲伤逆流成河小说齐铭结局写的两行字是啥 悲伤逆流成河齐铭喜欢谁

  • 华昌化工:致力于环保与可持续发展
    华昌化工:致力于环保与可持续发展

  • 世界首创!福建这一双塔平台,成为聚焦森林碳汇的“天眼”
    世界首创!福建这一双塔平台,成为聚焦森林碳汇的“天眼”

  • 正虹科技:7月销售生猪销售收入同比减少24.16%
    正虹科技:7月销售生猪销售收入同比减少24.16%

  • “ 20渝两江MTN002”将于8月15日召开持有人会议
    “ 20渝两江MTN002”将于8月15日召开持有人会议

  • 景德镇御窑遗址出土明代瓷器恭王府博物馆特展开展
    景德镇御窑遗址出土明代瓷器恭王府博物馆特展开展

  • 感觉高铁票越来越难买了?12306网站客服回应
    感觉高铁票越来越难买了?12306网站客服回应

巴山传媒网