filter的执行顺序
路由的filter可以配置多个。
如果是GatewayFilter,根据其在路由中的配置确定其执行顺序
1 2 3 4 5 6 7 8 9 10 11 12
| spring: cloud: gateway: routes: - id: path_route uri: http://www.baidu.com predicates: - Path=/get filters: - AddRequestHeader=X-Request-Foo, Bar - AddResponseHeader=X-Response-Foo, Bar - DedupeResponseHeader=Foo
|
又因为一个请求分为进pre和出post两个方向。放在前面的filter在pre过程中先执行,在post过程中后执行。

然后再加上GlobalFilter,和GatewayFilter的顺序会怎么执行呢?
根据Ordered接口
我们自定义GlobalFilter时,都会同时实现Ordered接口。
他只有一个方法getOrder(),返回优先级。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Bean public GlobalFilter customFilter() { return new CustomGlobalFilter(); }
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("custom global filter"); return chain.filter(exchange); }
@Override public int getOrder() { return -1; } }
|
数字越大,优先级越低,这个filter越靠后。
所以,源码中最高优先级的值就是Integer的最小值。
1 2 3 4 5 6 7 8 9 10 11 12
| /** * Useful constant for the highest precedence value. * @see java.lang.Integer#MIN_VALUE */ int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
/** * Useful constant for the lowest precedence value. * @see java.lang.Integer#MAX_VALUE */ int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
|
做个测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @Slf4j @Configuration public class GatewayTest { @Bean @Order(-1) public GlobalFilter a() { return (exchange, chain) -> { log.info("first pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("third post filter"); })); }; }
@Bean @Order(0) public GlobalFilter b() { return (exchange, chain) -> { log.info("second pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("second post filter"); })); }; }
@Bean @Order(1) public GlobalFilter c() { return (exchange, chain) -> { log.info("third pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("first post filter"); })); }; } }
|
触发一个请求,打印日志
1 2 3 4 5 6 7
| first pre filter second pre filter third pre filter
first post filter second post filter third post filter
|
也可以看出,“pre”类型的过滤器是在(exchanges,chain)->{}中执行的,
而“post”类型的过滤器是在chain.filter(exchange).then(Mono.fromRunnable(()->{}))中执行的。
以上代码,如果不喜欢lambda形式的写法,等价于以下写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Slf4j @Component public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
@Override public int getOrder() { return 1; }
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("third pre filter"); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("first post filter"); })); }
|