Spring Cloud Gateway网关过滤器详解

2022-07-06 14:37:59

(一)GlobalFilter

GlobalFilter和GatewayFilter的作用是相同的,只是GlobalFilter针对所有的路由配置生效。Spring Cloud Gateway内置的全局过滤器也有很多,比如∶
1:GatewayMetricsFilter,提供监控指标。
2:LoadBalancerClientFilter,整合Ribbon针对下游服务实现负载均衡。
3:ForwardRoutingFilter,用于本地forward,请求不转发到下游服务器。
4:NettyRoutingFilter,使用Netty的HttpClient转发HTTP、HTTPS请求。

全局过滤链的执行顺序是,当Gateway接收到请求时,Filtering Web Handler处理器会将所有的GlobalFilter实例及所有路由上所配置的GatewayFilter实例添加到一条过滤器链中。该过滤器链里的所有过滤器都会按照@Order注解所指定的数字大小进行排序。

(二)自定义过滤器

Spring Cloud Gateway提供了过滤器的扩展功能,开发者可以根据实际业务需求来自定义过滤器。同样,自定义过滤器也支持GlobalFilter和GatewayFilter两种。

(三)自定义Gateway Filter

首先创建一个自定义过滤器类GpDefineGatewayFilterFactory,继承AbstractGatewayFilterFactory。

@Service@Slf4jpublicclassGpDefineGatewayFilterFactoryextendsAbstractGatewayFilterFactory<GpDefineGatewayFilterFactory.GpConfig>{publicGpDefineGatewayFilterFactory(){super(GpConfig.class);}@OverridepublicGatewayFilterapply(GpConfig config){return((exchange, chain)->{ServerHttpRequest request= exchange.getRequest();
            log.info("前置局部过滤器,name:"+config.getName());return chain.filter(exchange).then(Mono.fromRunnable(()->{
                log.info("后置局部过滤器");}));});}publicstaticclassGpConfig{privateString name;publicStringgetName(){return name;}publicvoidsetName(String name){this.name= name;}}}

在上述代码中,有几点需要注意。
1:类名必须要统一以GatewayFilterFactory结尾,因为默认情况下过滤器的name会采用该自定义类的前缀。这里的name=GpDefine。
2:在apply方法中,同时包含Pre和Post过滤。在then方法中是请求执行结束之后的后置处理。
3:GpConfig是一个配置类,该类中只有一个属性name。这个属性可以在yml文件中使用。
4:该类需要装载到Spring IoC容器,此处使用@Service注解实现。

接下来,在application.yml文件中配置该自定义过滤器。
在这里插入图片描述

spring:cloud:gateway:routes:-id: define_filterpredicates:- Path=/gateway/**filters:-name: GpDefineargs:name: Gp_Mic-name: RequestRateLimiterargs:denyEmptyKey:falseemptyKeyStatus: SERVICE_UNAVAILABLEkeyResolver:'#{@ipAddressKeyResolver}'redis-rate-limiter.replenishRate:1redis-rate-limiter.burstCapacity:2- StripPrefix=1uri: http://localhost:8081/say

其中,name属性就是GpDefineGatewayFilterFactory的前缀。而args中的name属性是GpConfig配置类中声明的属性,这个属性配置好之后,可以在代码中获得这个name对应的值Gp_Mic

【提示】
对于请求中的Request和Response以及过滤器链可以通过如下对象获取
在这里插入图片描述

(四)自定义GlobalFilter

GlobalFilter的实现和JavaEE的方式类似,它不需要额外的配置,只需要实现GlobalFilter接口,自动会过滤所有的Route.

@Service@Slf4jpublicclassGpDefineFilterimplementsGlobalFilter,Ordered{@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){
        log.info("前置全局过滤器");return chain.filter(exchange).then(Mono.fromRunnable(()->{
            log.info("后置全局过滤器");}));}@OverridepublicintgetOrder(){return0;}}

getOrder表示该过滤器的执行顺序,值越小,执行优先级越高。
需要注意的是,我们通过AbstractGatewayFilterFactory实现的局部过滤器没有指定order,它的默认值是0,如果想要设置多个过滤器的执行顺序,可以重写getOrder方法。

【测试,运行程序并结合上面全局过滤器和局部过滤器】
在这里插入图片描述
在这里插入图片描述

  • 作者:ZWZhangYu
  • 原文链接:https://blog.csdn.net/Octopus21/article/details/117385359
    更新时间:2022-07-06 14:37:59