前言
在 Gateway 网关中,我们常使用以下两种过滤器:
- 全局过滤器:通过实现 GlobalFilter 创建,对所有路由生效,不需要单独配置。
- 自定义过滤器:通过实现 GatewayFilter 创建,只对与其绑定的特定路由生效,需要单独配置。
过滤器的执行过程分为两部分:Pre 和 Post
- Pre:请求转发前执行。
- Post:请求转发后返回响应结果时执行。
本文讨论的执行顺序都是指 Pre 过程多个过滤器的执行先后,Post 过程的执行顺序与 Pre 过程颠倒即可得到。
如何改变执行顺序
过滤器执行顺序的先后,其实只取决于一个值:Order 优先级。Order 值越小,优先级越高,越先执行。
因此,我们只要设置好 Order 值,就可以将过滤器的执行先后设置为期望的顺序。
这样就不需要再去纠结 全局过滤器和自定义过滤器哪个在前、优先级相同时哪个在前 之类的问题,因为我们已经将优先级设置好清晰地区分开来了。
最佳实践
第一步是全局过滤器(实现 GlobalFilter 接口)实现 Ordered 接口设置好优先级;
第二步是自定义过滤器(实现 GatewayFilter 接口)在配置类中定义路由时设置好优先级;并且同一个过滤器在不同路由中的优先级可以不同。
代码实现
全局过滤器:实现 Ordered 接口设置优先级
@Component
public class GaFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Ga");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 10;
}
}
@Component
public class GbFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Gb");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 20;
}
}
@Component
public class GcFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Gc");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 30;
}
}
自定义过滤器:
@Component
public class FaFilter implements GatewayFilter {
/**
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Fa");
return chain.filter(exchange);
}
}
@Component
public class FbFilter implements GatewayFilter/*, Ordered*/ {
/**
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Fb");
return chain.filter(exchange);
}
}
@Component
public class FcFilter implements GatewayFilter/*, Ordered*/ {
/**
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Fc");
return chain.filter(exchange);
}
}
配置类:将过滤器与路由绑定,同时设置好过滤器的优先级。
PS:两个不同的路由中,同一个过滤器的优先级可以是不同的。
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder,
FaFilter faFilter,
FbFilter fbFilter,
FcFilter fcFilter) {
return builder.routes()
.route("path_route_A", r -> r.path("/testA")
.filters(f -> f.filter(faFilter, 5).filter(fbFilter, 15).filter(fcFilter, 25))
.uri("http://127.0.0.1:8080")
)
.route("path_route_B", r -> r.path("/testB")
.filters(f -> f.filter(faFilter, 25).filter(fbFilter, 15).filter(fcFilter, 5))
.uri("http://127.0.0.1:8080")
)
.build();
}
}
结果
访问 /testA 路径:
Fa
Ga
Fb
Gb
Fc
Gc
访问 /testB 路径:
Fc
Ga
Fb
Gb
Fa
Gc
如果有帮助的话,可以点个赞支持一下嘛
🙏