当前位置: 首页 > news >正文

Spring-Cloud-Gateway的过滤器的执行顺序问题

过滤器的种类

Spring-Cloud-Gateway中提供了3种类型的过滤器,分别是:路由过滤器、Default过滤器和Global过滤器。

路由过滤器和Default过滤器

路由过滤器和Default过滤器本质上是同一种过滤器,只不过作用范围不一样,路由过滤器只针对单个路由起作用,而Default过滤器对整个路由表中所有的路由都起作用,这2个过滤器的处理逻辑都是Spring已经内置好的,无须开发人员来写代码,只需要做一下配置即可。

Spring已经提供好了30多种这样的过滤器,比如:

  • AddRequestHeader
  • AddRequestParameter
  • StripPrefix

  • 这些过滤器都是org.springframework.cloud.gateway.filter.GatewayFilter的子类,每一种过滤器都是由一种过滤器工厂来生成的,比如:
  • AddRequestHeaderGatewayFilterFactory生成AddRequestHeader的过滤器
  • AddRequestParameterGatewayFilterFactory生成AddRequestParameter的过滤器
  • StripPrefixGatewayFilterFactory生成StripPrefix的过滤器

Global过滤器

Global过滤器与上面两个不一样,Global过滤器需要开发人员自己来实现业务逻辑,并且它是org.springframework.cloud.gateway.filter.GlobalFilter的子类。

过滤器的执行顺序

如果是Global过滤器,可以让Global过滤器实现org.springframework.core.Ordered接口来设置过滤器的顺序,但是这里注意@org.springframework.core.annotation.Order这个注解是不起作用的。

如果是路由过滤器和Default过滤器,他们的处理逻辑是Spring内置的,因此,他们的顺序是按照声明的顺序,从1开始递增的,比如:

      routes:- id: userserviceuri: lb://userservicepredicates:- Path=/user/**filters:- AddRequestHeader=RouterFilter1, router1- AddRequestHeader=RouterFilter2, router2default-filters:- AddRequestHeader=DefaultFilter1, default1- AddRequestHeader=DefaultFilter1, default2

以上的配置种,router1的order是1,router2的order是2,default1的order是1,default2的order是2,也就是说按照他们声明的顺序,从1往上递增。

那么,当系统中同时存在这么多过滤器的时候,他们的执行顺序是什么样子的呢?比如,我现在同时定义了GlobalFilter1和GlobalFilter2,还有配置了router1、router2、default1、default2的时候:

@Component
public class GlobalFilter1 implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("============global1=============");return chain.filter(exchange);}@Overridepublic int getOrder() {return 2;}
}

还有GlobalFilter2:

@Component
public class GlobalFilter2 implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("============global2=============");return chain.filter(exchange);}@Overridepublic int getOrder() {return 1;}
}

只需要在org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()上打断点看一下即可:

@Override
public Mono<Void> handle(ServerWebExchange exchange) {Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);// 拿到所有的路由过滤器,包含了Default过滤器List<GatewayFilter> gatewayFilters = route.getFilters();// 拿到所有的Global过滤器List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);// 先添加的Global过滤器,然后再添加的路由过滤器combined.addAll(gatewayFilters);// TODO: needed or cached?AnnotationAwareOrderComparator.sort(combined);if (logger.isDebugEnabled()) {logger.debug("Sorted gatewayFilterFactories: " + combined);}// 在这一行打断点,查看下combined之后的内容return new DefaultGatewayFilterChain(combined).filter(exchange);
}

如下:
在这里插入图片描述
从源码种可以看出来,是先添加的Global过滤器,然后再添加的路由过滤器,从上面的截图也可以看出来,GlobalFilter2排在最前面,后面依次是default1、router1、GlobalFilter1、default2、router2。

可以继续在org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory#filter()方法和GlobalFilter上打断点,看一下后续的执行顺序。

因此,这些过滤器的执行顺序首先是根据order进行的排序,如果order相同,优先级是Global>Default>Router。

3种过滤器的类型都不一样为啥可以在一块进行排序?

Global过滤器是org.springframework.cloud.gateway.filter.GlobalFilter的子类,但是路由过滤器和Default过滤器是org.springframework.cloud.gateway.filter.GatewayFilter的子类,他们为啥可以放在一个集合中进行排序呢?
还是看org.springframework.cloud.gateway.handler.FilteringWebHandler这个类,它里面有一个loadFilters()方法:

private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {return filters.stream().map(filter -> {// 把GlobalFilter适配成了GatewayFilterAdapterGatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);// 并且这里计算顺序的时候,只是从Ordered接口取的if (filter instanceof Ordered) {int order = ((Ordered) filter).getOrder();return new OrderedGatewayFilter(gatewayFilter, order);}return gatewayFilter;}).collect(Collectors.toList());
}
// GatewayFilterAdapter 就实现了GatewayFilter接口
private static class GatewayFilterAdapter implements GatewayFilter {private final GlobalFilter delegate;GatewayFilterAdapter(GlobalFilter delegate) {this.delegate = delegate;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {return this.delegate.filter(exchange, chain);}
}

从上面的源码可以看出来,gateway框架在启动的时候,会把系统中所有的GlobalFilter适配成GatewayFilterAdapter ,而GatewayFilterAdapter 是实现了GatewayFilter 接口的,因此GlobalFilter也就适配成了GatewayFilter ,因此他们是可以放到一个集合进行排序的。同时可以看到,在获取GlobalFilter的order时候,只是使用Ordered接口并没有使用@Order注解。

结论

  • Global过滤器的顺序是由Ordered接口来定义,@Order不起作用。
  • 路由过滤器和Default过滤器的顺序是按照声明的顺序,从1开始递增
  • 所有的Global过滤器、路由过滤器、Default过滤器最终会放到一个集合中按照order大小进行排序
  • 如果order值一样,优先就是Global过滤器>Default过滤器>路由过滤器

ps:以上测试结论基于<spring-cloud.version>Hoxton.SR10</spring-cloud.version>

相关文章:

Spring-Cloud-Gateway的过滤器的执行顺序问题

过滤器的种类 Spring-Cloud-Gateway中提供了3种类型的过滤器&#xff0c;分别是&#xff1a;路由过滤器、Default过滤器和Global过滤器。 路由过滤器和Default过滤器 路由过滤器和Default过滤器本质上是同一种过滤器&#xff0c;只不过作用范围不一样&#xff0c;路由过滤器…...

Android性能优化的底层逻辑

前言性能优化仿佛成了每个程序员开发的必经之路&#xff0c;要想出人头地&#xff0c;与众不同&#xff0c;你还真需要下点功夫去研究Android的性能优化&#xff0c;比如说&#xff0c;从优化应用启动、UI加载、再到内存、CPU、GPU、IO、还有耗电等等&#xff0c;当你展开一个方…...

Gradle+SpringBoot多模块开发

关于使用Gradle结合SpringBoot进行多模块开发。 本来是打算使用buildSrc之类的&#xff0c;但是感觉好像好麻烦&#xff0c;使用这种方法就可以实现&#xff0c;没必要采用其他的。 我不怎么会表述&#xff0c;可能写的跟粑粑一样&#xff0c;哈哈哈哈 这是我的项目地址。 存在…...

Qt 之 emit、signals、slot的使用

本文福利&#xff0c;莬费领取Qt开发学习资料包、技术视频&#xff0c;内容包括&#xff08;C语言基础&#xff0c;Qt编程入门&#xff0c;QT信号与槽机制&#xff0c;QT界面开发-图像绘制&#xff0c;QT网络&#xff0c;QT数据库编程&#xff0c;QT项目实战&#xff0c;QSS&am…...

每日学术速递3.6

Subjects: cs.CV 1.Multi-Source Soft Pseudo-Label Learning with Domain Similarity-based Weighting for Semantic Segmentation 标题&#xff1a;用于语义分割的基于域相似性加权的多源软伪标签学习 作者&#xff1a;Shigemichi Matsuzaki, Hiroaki Masuzawa, Jun Miura …...

C# 将对象转换成字节数组(二进制数据)

在将自定义对象或者数组等这样的数据存储到数据库时往往需要转换成二进制字节&#xff0c;尤其是在一些O/RM数据库框架中&#xff0c;下面是转换的函数&#xff0c;一个是将对象转换成二进制字节数组&#xff0c;另一个是将从数据库中读取的二进制流转换成程序中的对象。 这里…...

巾帼绽芬芳 一起向未来(下篇)

编者按&#xff1a;为了隆重纪念纪念“三八”国际妇女节113周年&#xff0c;快来与你全方位、多层次分享交流“三八”国际妇女节的前世今生。分上篇&#xff08;节日简介、节日发展和节日意义&#xff09;、中篇&#xff08;节日活动宗旨和世界各国庆祝方式&#xff09;和下篇&…...

代码还原小试牛刀(一):魔改的MD5

一、目标 2023年了&#xff0c;MD5已经是最基础的签名算法了&#xff0c;但如果你还只是对输入做了简单的MD5&#xff0c;肯定会被同行们嘲笑。加点盐&#xff08;salt&#xff09;是一种基本的提升&#xff0c;但在这个就业形势严峻的时代&#xff0c;仅仅加盐肯定不够了。 …...

6. 找大佬

1 题目描述 找大佬成绩20开启时间2021年09月24日 星期五 18:00折扣0.8折扣时间2021年11月15日 星期一 00:00允许迟交否关闭时间2021年11月23日 星期二 10:00 众所周知&#xff0c;每个专业里都会有一些大佬隐藏在人群里。软件工程专业也是如此。今天的你就像从人群中找到真正的…...

【CSS】标签显示模式 ① ( 标签显示模式 | 块级元素 )

文章目录一、标签显示模式 ( 块级元素 | 行内元素 )二、块级元素1、块级元素简介2、块级元素特点3、文字块级元素4、代码示例一、标签显示模式 ( 块级元素 | 行内元素 ) 标签显示模式 : 指的是 标签显示的方式 , 标签类型有很多 , 不同的情景使用不同类型的标签 ; 块级元素 : …...

hive真实表空间大小统计

1. 问题 如果是采用hdfs上传加载的表、或者是flume直接写hdfs的表空间通常看hive的属性是不准确的。 2. 思路 为了使结果更精确&#xff0c;我们直接使用linux下命令统计hive仓库目录下的每个表对应的文件夹目录占用空间的大小。 3. 解决方法 这里建立三层表结构 ods: 原始…...

微信小程序引入Vant UI步骤

官方文档教程 1、通过 npm 安装 # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production2、修改 app.json 将 app.json 中的 “style”: “v2” 去除&#xff0c;小程序的新…...

【震撼发布】《致敬未来的攻城狮计划》| 文末赠书3本

《致敬未来的攻城狮计划》—— 文末有福利 摘要&#xff1a; 一个崭新的计划&#xff0c;寻找那群有志于向嵌入式发展的未来工程师&#xff01; 文章目录1 活动计划初衷2 活动计划形式3 活动计划收获4 活动计划要求5 活动计划时间6 活动计划致谢7 活动计划特别说明8 温馨提示9 …...

8.装饰者模式

目录 简介 角色组成 实现步骤 1. 新建 Log.class&#xff0c;添加如下代码 2. 新建 Log4j.class&#xff0c;继承 Log.class&#xff0c;并实现 record() 方法 3. 新建 Decorator.class&#xff0c;继承 Log.class 4. 新建 Log4jDecorator.class&#xff0c;继承 Decorat…...

GIT基础常用命令-1 GIT基础篇

git基础常用命令-1 GIT基础篇1.git简介及配置1.1 git简介1.2 git配置config1.2.1 查看配置git config1.2.2 配置设置1.2.3 获取帮助git help2 GIT基础常用命令2.1 获取镜像仓库2.1.1 git init2.1.2 git clone2.2 本地仓库常用命令2.2.1 git status2.2.2 git add2.2.3 git diff2…...

华为OD机试题,用 Java 解【数列描述】问题

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…...

2022掉队的“蔚小理”,按下了兔年加速键

配图来自Canva可画 进入2023年&#xff0c;各大车企又展开了新一轮的“竞速”。尽管1月份汽车整体销量出现了“阴跌”&#xff0c;但从各路车企发布的销量目标来看&#xff0c;车企对于2023依旧保持着较高的信心和预期。在一众车企中&#xff0c;以“蔚小理”为代表的新势力们…...

【NLP相关】attention的代码实现

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️&#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…...

凌恩生物资讯

凌恩生物转录组项目包含范围广&#xff0c;项目经验丰富&#xff0c;人均10年以上项目经验&#xff0c;其中全长转录组测序研究基因结构已经成为发文章的趋势&#xff0c;研究物种包括高粱、玉米、拟南芥、鸡、人和小鼠、毛竹、棉花等。凌恩生物提供专业的全长转录组测序及分析…...

Leetcode 148. 排序链表(二路归并)

题目&#xff1a;    给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 解法一&#xff1a;    递归解法&#xff0c;自顶向下    链表版二路归并排序&#xff08;升序&#xff0c;递归版&#xff09;&#xff0c;稳定排序    时间复杂度…...

基于Claude API的智能银行应用原型:AI-First前端交互架构实践

1. 项目概述&#xff1a;一个基于Claude API的智能银行应用原型 最近在GitHub上看到一个挺有意思的开源项目&#xff0c;叫“ClaudeBankingApp”。光看名字&#xff0c;你可能会觉得这是个什么复杂的金融科技产品&#xff0c;其实不然。这是一个由开发者tzockoll-creator创建的…...

CANoe VN1640A的隐藏技能:CH5 I/O口实战应用,从采集电压到模拟传感器信号

CANoe VN1640A的CH5 I/O接口深度实战&#xff1a;从电压采集到传感器信号模拟 1. 揭开CH5接口的神秘面纱 在汽车电子测试领域&#xff0c;Vector的VN1640A接口模块以其稳定性和多功能性著称。大多数工程师熟悉其CAN/LIN通道的使用&#xff0c;却常常忽略了一个隐藏的宝藏——…...

G-Helper终极教程:华硕笔记本轻量级性能控制神器

G-Helper终极教程&#xff1a;华硕笔记本轻量级性能控制神器 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Expertb…...

基于STM32单片机人体健康检测血糖检测监测无线蓝牙APP设计S312

本系统由STM32F103C8T6单片机核心板、OLED屏、无线模块、血糖模拟检测、蜂鸣器报警、电源电路、按键电路组成。【1】液晶显示&#xff1a;OLED液晶显示心率值、心率上下限、血氧值、血氧阈值、血压值、血压阈值、血糖值、血糖上下限值以及心率血氧是否在采集测算中、当前数据是…...

信号与线性系统分析(吴大正第5版)自学避坑指南:这些印刷错误和公式笔误你遇到了吗?

信号与线性系统分析&#xff08;吴大正第5版&#xff09;自学避坑指南&#xff1a;这些印刷错误和公式笔误你遇到了吗&#xff1f; 当你独自面对《信号与线性系统分析》这本经典教材时&#xff0c;是否曾因某个公式推导卡壳数小时&#xff1f;是否反复检查自己的计算步骤&#…...

终极指南:如何快速解决LaTeX中文排版字体问题

终极指南&#xff1a;如何快速解决LaTeX中文排版字体问题 【免费下载链接】latex-chinese-fonts Simplified Chinese fonts for the LaTeX typesetting. 项目地址: https://gitcode.com/gh_mirrors/la/latex-chinese-fonts 还在为LaTeX中文排版时遇到的字体缺失、样式混…...

taskwarrior-tui键盘绑定完全手册:成为效率达人的秘密武器

taskwarrior-tui键盘绑定完全手册&#xff1a;成为效率达人的秘密武器 【免费下载链接】taskwarrior-tui taskwarrior-tui: A terminal user interface for taskwarrior 项目地址: https://gitcode.com/gh_mirrors/ta/taskwarrior-tui taskwarrior-tui是一款功能强大的终…...

高性能小程序跨框架迁移方案:miniprogram-to-vue3自动化转换架构设计与最佳实践

高性能小程序跨框架迁移方案&#xff1a;miniprogram-to-vue3自动化转换架构设计与最佳实践 【免费下载链接】miniprogram-to-vue3 项目地址: https://gitcode.com/gh_mirrors/mi/miniprogram-to-vue3 随着前端技术生态的快速发展&#xff0c;微信小程序向Vue3/Uniapp3…...

国产多模态大模型“看懂”世界:视觉问答(VQA)全解析

国产多模态大模型“看懂”世界&#xff1a;视觉问答(VQA)全解析 引言 在人工智能浪潮中&#xff0c;让机器“看懂”图片并回答问题的能力&#xff0c;正从科幻走向现实。国产多模态大模型在视觉问答&#xff08;Visual Question Answering, VQA&#xff09;领域异军突起&#x…...

088、机器人动力学:牛顿-欧拉法

机器人动力学:牛顿-欧拉法 从一次机械臂抖动说起 去年调试一台六轴协作机器人,空载运行还算平稳,一夹持3kg负载做高速圆弧插补,末端就开始高频抖动。PID参数调了三轮,陷波滤波器加了两个,效果都不理想。后来拆开关节看,发现电机电流波形在加减速阶段有明显的毛刺——这…...