轉自 : https://www.cnblogs.com/westlin/p/10911945.html
學習官方文檔,發現對於過濾器有分為三類
- 默認過濾器
- 自定義過濾
- 全局過濾器
准備階段
過濾器工廠類
以此為模板,復制出幾份就可以了,注意打印信息,可區分就行
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<Void> 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); } }
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(后置)過濾器就后被執行了。
場景二
自定義過濾器和默認過濾器都保留為相同的order
順序
@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
順序空間,即他們會按照各自的順序來進行排序