gateway 过滤器执行顺序_spring boot gateway 过滤器的执行顺序

前言

学习官方文档,发现对于过滤器有分为三类

默认过滤器

自定义过滤

全局过滤器

于是就有一个疑问,关于这些过滤器的访问顺序是怎样的,今天就以一个demo来进行测试

准备阶段

过滤器工厂类

以此为模板,复制出几份就可以了,注意打印信息,可区分就行

public class ExampleGatewayFilterFactory extends AbstractGatewayFilterFactory {

/**

* 创造出的过滤器的顺序

*/

private int order;

/**

* constructor

*/

public ExampleGatewayFilterFactory(int order) {

this.order = order;

}

@Override

public GatewayFilter apply(Object config) {

return new InnerFilter();

}

/**

* 创建一个内部类,来实现2个接口,指定顺序

*/

private class InnerFilter implements GatewayFilter, Ordered {

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

System.out.println(" pre 自定义过滤器工厂 " + this.getClass().getSimpleName());

// 在then方法里的,相当于aop中的后置通知

return chain.filter(exchange).then(Mono.fromRunnable(() -> {

System.out.println(" post 自定义过滤器工厂 " + this.getClass().getSimpleName());

}));

}

@Override

public int getOrder() {

return order;

}

}

}

过滤器配置类

这里我们设置了

2个默认过滤器

2个自定义过滤器,

1个全局过滤器

@SpringBootConfiguration

public class FilterConfig {

// 以下是全局的过滤器(注意这里我们保持它为最高优先级)

@Bean

@Order(value = Ordered.HIGHEST_PRECEDENCE)

public GlobalFilter costFilter(){

return new CostFilter();

}

// 以下是自定义的的过滤器工厂

@Bean

public GatewayFilterFactory exampleAGatewayFilterFactory(){

return new ExampleAGatewayFilterFactory(0);

}

@Bean

public GatewayFilterFactory exampleGatewayFilterFactory(){

return new ExampleGatewayFilterFactory(1);

}

// 以下是默认过滤工厂

@Bean

public GatewayFilterFactory myDefaultGatewayFilterFactory(){

return new MyDefaultGatewayFilterFactory(2);

}

@Bean

public GatewayFilterFactory myDefaultAAGatewayFilterFactory(){

return new MyDefaultAAGatewayFilterFactory(3);

}

}

springboot启动类

// 这里扫描基础包,可以把其他配置加入进来

@SpringBootApplication(scanBasePackages = {"com.example.gateway"})

public class GatewayApplication {

public static void main(String[] args) {

SpringApplication.run(GatewayApplication.class, args);

}

}

application.yml文件的配置

spring:

application:

name: demo-gateway

cloud:

gateway:

discovery:

locator:

enabled: true

routes:

- id: to-route

uri: lb://demo-consumer

# 例如访问 localhost:8080/route会路由到demo-consumer的服务下的/route接口

predicates:

- Path=/route

- id: to-account

uri: lb://demo-consumer

predicates:

- Path=/account/v1/**

filters:

- name: ExampleA

- name: Example

# 默认过滤器

default-filters:

- name: MyDefaultAA

- name: MyDefault

测试

场景一

按照准备阶段的配置order顺序,来看访问的结果

pre 自定义过滤器工厂 AAAA InnerFilter

pre 自定义过滤器工厂 InnerFilter

pre 【默认】过滤器工厂 InnerFilter

pre 【默认AAA】过滤器工厂 InnerFilter

pre 全局过滤器 CostFilter

post 全局过滤器 CostFilter

post 【默认AAA】过滤器工厂 InnerFilter

post 【默认】过滤器工厂 InnerFilter

post 自定义过滤器工厂 InnerFilter

post 自定义过滤器工厂 AAAA InnerFilter

过滤器的执行顺序与堆栈这个数据结构很想,LIFO,gateway中的过滤器只有前置和后置2个生命周期,pre中后触发的,在post中就先被执行了

从输出的打印来看,默认过滤器和自定义的过滤器按照我们定义的1 2 3 4的顺序,成功的打印了出来,而全局过滤器是在最后才执行

场景二

自定义过滤器和默认过滤器都保留为相同的order顺序

修改如下,都统一为是0

@Bean

public GatewayFilterFactory exampleAGatewayFilterFactory(){

return new ExampleAGatewayFilterFactory(0);

}

@Bean

public GatewayFilterFactory exampleGatewayFilterFactory(){

return new ExampleGatewayFilterFactory(0);

}

// 以下是默认过滤工厂

@Bean

public GatewayFilterFactory myDefaultGatewayFilterFactory(){

return new MyDefaultGatewayFilterFactory(0);

}

@Bean

public GatewayFilterFactory myDefaultAAGatewayFilterFactory(){

return new MyDefaultAAGatewayFilterFactory(0);

}

返回的结果

pre 【默认AAA】过滤器工厂 InnerFilter

pre 【默认】过滤器工厂 InnerFilter

pre 自定义过滤器工厂 AAAA InnerFilter

pre 自定义过滤器工厂 InnerFilter

pre 全局过滤器 CostFilter

post 全局过滤器 CostFilter

post 自定义过滤器工厂 InnerFilter

post 自定义过滤器工厂 AAAA InnerFilter

post 【默认】过滤器工厂 InnerFilter

post 【默认AAA】过滤器工厂 InnerFilter

注意到我们前面在yml中配置的过滤器的顺序是

filters:

- name: ExampleA

- name: Example

# 默认过滤器

default-filters:

- name: MyDefaultAA

- name: MyDefault

这与前面几行的输出结果一致,所以如果当优先order一样的前提下,默认过滤器的执行优先于自定义过滤器,过滤器的执行顺序是与你在yml中声明的顺序是一致的。

全局过滤器依然是最后一个执行的

场景三

我们将自定义过滤器和默认过滤的顺序按照穿插的来,即

自定义、默认、自定义、默认

// 以下是自定义的的过滤器工厂

@Bean

public GatewayFilterFactory exampleAGatewayFilterFactory(){

return new ExampleAGatewayFilterFactory(1);

}

@Bean

public GatewayFilterFactory exampleGatewayFilterFactory(){

return new ExampleGatewayFilterFactory(3);

}

// 以下是默认过滤工厂

@Bean

public GatewayFilterFactory myDefaultGatewayFilterFactory(){

return new MyDefaultGatewayFilterFactory(2);

}

@Bean

public GatewayFilterFactory myDefaultAAGatewayFilterFactory(){

return new MyDefaultAAGatewayFilterFactory(4);

}

运行访问后的执行结果如下

pre 自定义过滤器工厂 AAAA InnerFilter

pre 【默认】过滤器工厂 InnerFilter

pre 自定义过滤器工厂 InnerFilter

pre 【默认AAA】过滤器工厂 InnerFilter

pre 全局过滤器 CostFilter

post 全局过滤器 CostFilter

post 【默认AAA】过滤器工厂 InnerFilter

post 自定义过滤器工厂 InnerFilter

post 【默认】过滤器工厂 InnerFilter

post 自定义过滤器工厂 AAAA InnerFilter

可以看到它是按照我们书写的顺序来的

结论

全局过滤器与其他2类过滤器相比,永远是最后执行的;它的优先级只对其他全局过滤器起作用

当默认过滤器与自定义过滤器的优先级一样时,优先出发默认过滤器,然后才是自定义过滤器;同类型的过滤器,出发顺序与他们在配置文件中声明的顺序一致

默认过滤器与自定义过滤器使用同样的order顺序空间,即他们会按照各自的顺序来进行排序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 线程状态流转

Java 线程一共有 6 种状态: NEW:新建状态,当一个线程被创建完成,还没有调用 start() 方法时,是这种状态。RUNNABLE:可运行状态,当一个线程正在正常地执行 run() 中的代码时,是这种状…

达梦数据库导入oracle数据_达梦数据库和oracle数据的一些区别

近期我在考达梦的dca发现有一些和oracle不同的地方,由于我是oracleDBA在维护达梦数据库的时候有需要注意的地方,现在分享一下2个数据库的一些区别。1、登陆的区别oracle:如果sys的密码忘记可以用操作系统验证方式登陆修改密码。dm:达梦数据库如果忘记了s…

Fail-fast 和 Fail-safe 机制

fail-fast 和 fail-safe 的区别 从字面意思来看 fail-fast 是快速失败,fail-safe 是安全失败,这都是集合类对于并发读写时的一种应对机制。 fail-fast,广泛应用于 java.util 下的集合类中,其机制为在使用迭代器遍历的过程中&…

【java8新特性】——lambda表达式与函数式接口详解(一)

一、简介 java8于2014年发布,相比于java7,java8新增了非常多的特性,如lambda表达式、函数式接口、方法引用、默认方法、新工具(编译工具)、Stream API、Date Time API、Optional等 。 当前很多公司的老产品依然使用的…

详解 ConcurrentHashMap

文章目录ConcurrentHashMap 的底层数据结构?ConcurrentHashMap 的带参构造方法的流程?ConcurrentHashMap 的 put 方法的流程?ConcurrentHashMap addCount 方法的流程是怎样的呢?ConcurrentHashMap transfer 方法的流程是怎样的呢?Concurren…

js 二叉树图形_js数据结构和算法(三)二叉树

二叉树的概念二叉树(Binary Tree)是n(n>0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。二叉树的特点每个结点最多有两棵子树,所以二叉树中不存在度大于…

【java8新特性】——Stream API详解(二)

一、简介 java8新添加了一个特性:流Stream。Stream让开发者能够以一种声明的方式处理数据源(集合、数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation)和大批量数据操作 (bulk data op…

Spring bean 不被 GC 的真正原因

概述 自从开始接触 Spring 之后,一直以来都在思考一个问题,在 Spring 应用的运行过程中,为什么这些 bean 不会被回收? 今天深入探究了这个问题之后,才有了答案。 思考点 大家都知道,一个 bean 会不会被回…

ad域时间源配置_域控制器server2012时间同步NTP配置

一、域控配置1.修改注册表,设置域控服务器名称2.设置组策略,启动NTP服务器3.域策略中设置windows time服务自动启动二、服务端配置(Ntp服务器,客户端将根据这台服务器的时间进行同步)1、微软键R键,进入“运行”,输入“…

【java8新特性】——Optional详解(三)

一、简介 Optional类是Java8为了解决null值判断问题,借鉴google guava类库的Optional类而引入的一个同名Optional类,使用Optional类可以避免显式的null值判断(null的防御性检查),避免null导致的NPE(NullPo…

不使用 + 和 - 运算符计算两整数之和

问题概述 不使用运算符 和 -,计算两整数之和 思考 不使用 和 - ,那就只能想到用位运算来处理了。思路如下: 两数进行 ^(异或运算),可以得到两个数在相同位上数值不同的相加结果两数进行 &&#x…

vts传感器采取船舶的_详解虎门大桥监测系统:传感器与物联网功不可没

来源:传感器专家网近日,虎门大桥“虎躯一震”给全国人民来了个“深呼吸”。虎门大桥是广东沿海地区重要的交通枢纽,始建于1992年,1997年通车至今,大桥一直都十分平稳。但在5月5日下午,虎门大桥发生异常抖动…

宝塔安装sqlserver_linux宝塔面板安装安装 pdo_sqlsrv扩展

第一步安装源curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssqlrelease.repo第二步安装驱动yum install msodbcsql mssql-tools unixODBC-devel第三步下载pdo-sqlsrv源码wget http://pecl.php.net/get/pdo_sqlsrv-5.6.1.tgztar -zxvf …

【java8新特性】——方法引用(四)

一、简介 方法引用是java8的新特性之一&#xff0c; 可以直接引用已有Java类或对象的方法或构造器。方法引用与lambda表达式结合使用&#xff0c;可以进一步简化代码。 来看一段简单代码&#xff1a; public static void main(String[] args) {List<String> strList Ar…

MySQL 排名函数.md

概述 MySQL 自带的排名的函数&#xff0c;主要有&#xff1a; row_number()rank()dense_rank()ntile() 测试数据 测试数据如下所示&#xff1a; row_number() 函数 用法如下&#xff1a; SELECT row_number() OVER (ORDER BY Salary DESC) row_num,Salary FROMEmployee查…

【java8新特性】——默认方法(五)

一、简介 默认方法是指接口的默认方法&#xff0c;它是java8的新特性之一。顾名思义&#xff0c;默认方法就是接口提供一个默认实现&#xff0c;且不强制实现类去覆写的方法。默认方法用default关键字来修饰。 默认方法可以解决的痛点&#xff1a; 在java8之前&#xff0c;修…

Java 序列化总结.md

概述 序列化&#xff1a;将对象写入到 IO 流中反序列化&#xff1a;从 IO 流中恢复对象 实现方法 实现 Serializable 或者 Externalizable Serializable&#xff1a;标记接口&#xff0c;不用实现任何方法&#xff0c;可以指定序列化 IDExternalizable&#xff1a;增强的序…

多线程买票案例

测试类 package thead;public class testThread {public static void main(String [] arg){Tickets ticket new Tickets();Thread t1 new Thread(ticket,"窗口一&#xff1a;");Thread t2 new Thread(ticket,"窗口二&#xff1a;");Thread t3 new Thr…

深度学习auc_机器学习集成学习与模型融合!

↑↑↑关注后"星标"Datawhale每日干货 & 每月组队学习&#xff0c;不错过Datawhale干货 作者&#xff1a;李祖贤&#xff0c;深圳大学&#xff0c;Datawhale高校群成员对比过kaggle比赛上面的top10的模型&#xff0c;除了深度学习以外的模型基本上都是集成学习的…

常用并发工具类(锁和线程间通信工具类)

常用并发工具类总结 JUC 下的常用并发工具类&#xff08;锁和线程间通信工具类&#xff09;&#xff0c;主要包括 ReentrantLock、ReentrantReadWriteLock、CountDownLatch、CyclicBarrier、Semaphore、Exchanger ReentrantLock 和 ReentrantReadWriteLock ReentrantLock 是…