Gateway过滤器执行顺序配置的最佳实践


前言

在 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

如果有帮助的话,可以点个赞支持一下嘛🙏

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值