• 深入解析Spring Cloud Gateway的GlobalFilter


    摘要

    本文将详细介绍Spring Cloud Gateway中的GlobalFilter,解释其作用以及如何使用。通过代码示例,读者将深入了解GlobalFilter在Spring Cloud Gateway中的应用,以及如何自定义和配置GlobalFilter来实现定制化的网关逻辑。

    引言

    Spring Cloud Gateway是Spring Cloud生态系统中的一员,是基于Spring Framework 5、Project Reactor和Spring Boot 2构建的非阻塞网关。GlobalFilter是Spring Cloud Gateway中一个重要的组件,用于在请求经过网关时进行全局的处理操作。本文将详细介绍GlobalFilter的作用和使用方式。

    GlobalFilter的作用

    GlobalFilter是Spring Cloud Gateway中的全局过滤器,它能够对所有的请求进行拦截和处理。GlobalFilter通常用于实现一些全局的功能,如请求日志记录、请求鉴权、异常处理等。通过GlobalFilter,我们可以在请求经过网关之前或之后进行一系列的操作,以满足特定的需求。

    使用GlobalFilter

    默认的GlobalFilter

    Spring Cloud Gateway默认提供了一些全局过滤器,用于实现一些常见的功能。例如,GlobalFilter接口的实现类ForwardRoutingFilter用于将请求转发到目标服务,AddResponseHeaderFilter用于添加响应头等。通过配置文件或代码的方式,我们可以使用这些默认的GlobalFilter来实现基本的网关功能。

    自定义GlobalFilter

    除了使用默认的GlobalFilter,我们还可以自定义GlobalFilter来实现定制化的网关逻辑。自定义GlobalFilter需要实现GlobalFilter接口,并重写filter方法。在该方法中,我们可以编写自己的逻辑来处理请求。通过使用自定义GlobalFilter,我们可以实现更加灵活和个性化的网关功能。

    示例代码

    下面通过示例代码,演示如何使用GlobalFilter来实现请求日志记录的功能。

    @Component
    public class LoggingFilter implements GlobalFilter, Ordered {
    	
    	private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
      
    	@Override
    	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    		logger.info("Request URL: {}", exchange.getRequest().getURI());
    		logger.info("Request Method: {}", exchange.getRequest().getMethod());
    		logger.info("Request Headers: {}", exchange.getRequest().getHeaders());
    		return chain.filter(exchange);
    	}
    	
    	@Override
    	public int getOrder() {
    		return Ordered.HIGHEST_PRECEDENCE;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在上述示例代码中,我们定义了一个名为LoggingFilter的自定义GlobalFilter。在filter方法中,我们通过ServerWebExchange对象获取请求的URL、方法和请求头,并使用日志记录下来。最后,通过调用 chain.filter(exchange) 将请求继续传递给下一个过滤器或目标服务。

    为了确保自定义GlobalFilter的执行顺序,我们还需要实现Ordered接口,并重写 getOrder 方法来指定过滤器的执行顺序。在示例代码中,我们使用了 Ordered.HIGHEST_PRECEDENCE 来确保该过滤器是第一个执行的。

    配置GlobalFilter

    要使用自定义的GlobalFilter,我们需要将其注册到Spring Cloud Gateway中。可以通过配置文件或代码的方式进行注册。

    配置文件方式

    在application.yml或application.properties文件中添加以下配置:

    spring:
      cloud:
        gateway:
          global-filters:
            - com.example.LoggingFilter
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上述配置将LoggingFilter注册为全局过滤器。

    代码方式

    在Spring Boot的启动类中,使用@Bean注解将LoggingFilter注册为Bean:

    @SpringBootApplication
    public class GatewayApplication {
    	
    	public static void main(String[] args) {
    		SpringApplication.run(GatewayApplication.class, args);
    	}
    	
    	@Bean
    	public LoggingFilter loggingFilter() {
    		return new LoggingFilter();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通过上述配置,我们将LoggingFilter注册为全局过滤器。

    高级用法:重写GlobalFilter

    在工作中避免不了要自定义starter,以插件的方式引入一些特殊的逻辑,但是同时还要做到用户可拓展。在starter中,可以通过实现GlobalFilter接口来编写全局过滤器。用户在引入starter后,可以通过在自己的应用中重新定义这个过滤器来覆盖starter中的默认实现。

    思路

    在starter中,可以通过@ConditionalOnMissingBean注解来判断当前应用中是否已经定义了该类型的bean。如果没有定义,则使用starter中的默认实现;如果有定义,则使用应用中的实现。

    代码实现

    1. 假设我们在starter中定义了一个名为MyGlobalFilter的全局过滤器:

      public class MyGlobalFilter implements GlobalFilter {
      	@Override
      	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      		// 默认实现
      		return chain.filter(exchange);
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    2. 我们可以在starter中为这个过滤器添加@ConditionalOnMissingBean注解,以确保只有在应用中没有定义该类型的bean时才会使用默认实现:

      @Configuration
      public class MyConfiguration {
          @Bean
          @ConditionalOnMissingBean
          public GlobalFilter myGlobalFilter() {
              return new MyGlobalFilter();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    3. 如果用户在自己的应用中想要覆盖这个过滤器的逻辑,只需要定义一个同名的bean即可。例如,用户可以在自己的应用中定义一个名为MyGlobalFilter的bean:

      @Bean
      public GlobalFilter myGlobalFilter() {
          return (exchange, chain) -> {
              // 自定义实现
              return chain.filter(exchange);
          };
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    这样,在应用启动时,Spring会发现应用中已经有了一个名为MyGlobalFilter的bean,就会使用该实现代替starter中的默认实现。

    总结起来,starter中的全局过滤器应该使用 @ConditionalOnMissingBean 注解,以便用户可以在自己的应用中重新定义该过滤器的实现。用户只需要定义一个同名的bean即可覆盖starter中的默认实现。

    结论

    在本文中,我们详细介绍了Spring Cloud Gateway中的GlobalFilter,并解释了它的作用和使用方式。通过自定义GlobalFilter,我们可以实现定制化的网关逻辑。通过配置文件或代码,我们可以注册和配置GlobalFilter来达到期望的效果。希望本文对读者在使用Spring Cloud Gateway时有所帮助,并能更好地应用于实际项目中。

    参考文献

    如果大家遇到类似问题,欢迎评论区讨论,如有错误之处,敬请留言。

    在这里插入图片描述

  • 相关阅读:
    2024最新 Jenkins + Docker实战教程(八)- Jenkins实现集群并发构建
    Flutter | 验证码的倒计时进入后台停止了怎么办?
    Css 设置从上到下的渐变色: 0到70%为yellow,然后线性地变成透明。
    【11.25】【VP】 45 届 济南站
    详解八大排序
    【Linux】- 一文秒懂shell编程
    Python 爬取 "王者荣耀.英雄壁纸" 过程中的矛和盾
    大数据实战之HDFS单机配置
    当JAVA注解、AOP、SpEL相遇,更多可能变为了现实
    layer 弹窗,enter 、esc 按键监听确定、取消事件
  • 原文地址:https://blog.csdn.net/weixin_47264624/article/details/133789166