Spring Cloud Gateway全局過濾器GlobalFilter初探

定義

【spring cloud gateway】的官方文檔中,全局過濾器GlobalFilter接口是這樣定義的:html

The GlobalFilter interface has the same signature as GatewayFilter. These are special filters that are conditionally applied to all routes. (This interface and usage are subject to change in future milestones).
  • GlobalFilter 和 GatewayFilter 的 #filter(ServerWebExchange, GatewayFilterChain) 方法簽名一致;
  • GlobalFilter會做用於全部的路由上;
  • 在將來的里程碑版本中可能做一些調整;

org.springframework.cloud.gateway.filter.GlobalFilter,接口源代碼:java

public interface GlobalFilter {

    /**
     * Process the Web request and (optionally) delegate to the next
     * {@code WebFilter} through the given {@link GatewayFilterChain}.
     * @param exchange the current server exchange
     * @param chain provides a way to delegate to the next filter
     * @return {@code Mono<Void>} to indicate when request processing is complete
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

GlobalFilter實現類

關於GlobalFilter接口內置的實現類主要有11個,均位於 org.springframework.cloud.gateway.filter 包中,以下:git

圖片描述

IDEA查看類圖快捷鍵github

  • Ctrl + Alt + Shift + U:查看GlobalFilter類圖;
  • Ctrl + T:查看GlobalFilter接口的全部實現類;

各個實現類的順序以下( 數值越小,優先級越高,括號中爲源碼中的值 ):web

  • AdaptCachedBodyGlobalFilter-2147482648 ( Ordered.HIGHEST_PRECEDENCE + 1000 )
  • ForwardPathFilter0
  • ForwardRoutingFilter2147483647 ( Ordered.LOWEST_PRECEDENCE )
  • GatewayMetricsFilter0
  • LoadBalancerClientFilter10100
  • NettyRoutingFilter2147483647 ( Ordered.LOWEST_PRECEDENCE )
  • NettyWriteResponseFilter-1
  • RouteToRequestUrlFilter10000
  • WebClientHttpRoutingFilter2147483647 ( Ordered.LOWEST_PRECEDENCE )
  • WebClientWriteResponseFilter-1
  • WebsocketRoutingFilter2147483646 ( Ordered.LOWEST_PRECEDENCE - 1 )

其中關於 org.springframework.core.Ordered 類源碼以下:spring

package org.springframework.core;

public interface Ordered {
    int HIGHEST_PRECEDENCE = -2147483648;
    int LOWEST_PRECEDENCE = 2147483647;

    int getOrder();
}

GlobalFilter實現類實例化配置

各個GlobalFilter實現類具體實例化分別是在 org.springframework.cloud.gateway.config.GatewayAutoConfigurationorg.springframework.cloud.gateway.config.GatewayLoadBalancerClientAutoConfigurationorg.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration 中配置的,以下:json

一、GatewayAutoConfiguration

在GatewayAutoConfiguration中配置的GlobalFilter實現類主要有瀏覽器

  • AdaptCachedBodyGlobalFilter
  • RouteToRequestUrlFilter
  • ForwardRoutingFilter
  • ForwardPathFilter
  • WebsocketRoutingFilter

在gateway-core 2.0.1版本中被註釋掉的兩個websocket

  • WebClientHttpRoutingFilter
  • WebClientWriteResponseFilter

相關源代碼以下:app

// GlobalFilter beans

    @Bean
    public AdaptCachedBodyGlobalFilter adaptCachedBodyGlobalFilter() {
        return new AdaptCachedBodyGlobalFilter();
    }

    @Bean
    public RouteToRequestUrlFilter routeToRequestUrlFilter() {
        return new RouteToRequestUrlFilter();
    }

    @Bean
    @ConditionalOnBean(DispatcherHandler.class)
    public ForwardRoutingFilter forwardRoutingFilter(DispatcherHandler dispatcherHandler) {
        return new ForwardRoutingFilter(dispatcherHandler);
    }

    @Bean
    public ForwardPathFilter forwardPathFilter() {
        return new ForwardPathFilter();
    }

    @Bean
    public WebSocketService webSocketService() {
        return new HandshakeWebSocketService();
    }

    @Bean
    public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient,
                                                         WebSocketService webSocketService,
                                                         ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
        return new WebsocketRoutingFilter(webSocketClient, webSocketService, headersFilters);
    }

    @Bean
    public WeightCalculatorWebFilter weightCalculatorWebFilter(Validator validator) {
        return new WeightCalculatorWebFilter(validator);
    }

    /*@Bean
    //TODO: default over netty? configurable
    public WebClientHttpRoutingFilter webClientHttpRoutingFilter() {
        //TODO: WebClient bean
        return new WebClientHttpRoutingFilter(WebClient.routes().build());
    }

    @Bean
    public WebClientWriteResponseFilter webClientWriteResponseFilter() {
        return new WebClientWriteResponseFilter();
    }*/

二、GatewayAutoConfiguration.NettyConfiguration

在GatewayAutoConfiguration.NettyConfiguration中配置的GlobalFilter實現類主要有

  • NettyRoutingFilter
  • NettyWriteResponseFilter

相關源代碼以下:

@Bean
  public NettyRoutingFilter routingFilter(HttpClient httpClient,
                                          ObjectProvider<List<HttpHeadersFilter>> headersFilters,
                                          HttpClientProperties properties) {
      return new NettyRoutingFilter(httpClient, headersFilters, properties);
  }

  @Bean
  public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
      return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
  }

三、GatewayLoadBalancerClientAutoConfiguration

在GatewayLoadBalancerClientAutoConfiguration中配置的GlobalFilter實現類主要有

  • LoadBalancerClientFilter

相關源代碼以下:

@Configuration
@ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
@AutoConfigureAfter(RibbonAutoConfiguration.class)
public class GatewayLoadBalancerClientAutoConfiguration {

    // GlobalFilter beans

    @Bean
    @ConditionalOnBean(LoadBalancerClient.class)
    public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
        return new LoadBalancerClientFilter(client);
    }
}

四、GatewayMetricsAutoConfiguration

在GatewayMetricsAutoConfiguration中配置的GlobalFilter實現類主要有

  • GatewayMetricsFilter

相關源代碼以下:

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({ MetricsAutoConfiguration.class,
        CompositeMeterRegistryAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class, MeterRegistry.class, MetricsAutoConfiguration.class})
public class GatewayMetricsAutoConfiguration {
    @Bean
    @ConditionalOnBean(MeterRegistry.class)
    @ConditionalOnProperty(name = "spring.cloud.gateway.metrics.enabled", matchIfMissing = true)
    public GatewayMetricsFilter gatewayMetricFilter(MeterRegistry meterRegistry) {
        return new GatewayMetricsFilter(meterRegistry);
    }
}

經過內置監控端點查看實際實例化的GlobalFilter實現類

一、首先引入actuator模塊,添加以下依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

二、在配置文件application.yml中開啓監控管理端點

management:
  endpoint:
    gateway:
      enabled: true
  endpoints:
    web:
      exposure:
        include: "*"

若是不進行如上配置,默認狀況下只會看到下面的三個路由:

  • /actuator/health
  • /actuator/info
  • /actuator

配置以後,就能夠看到有關 GlobalFilter 的端點路由信息:

  • /actuator/gateway/globalfilters

三、在瀏覽器中訪問 http://localhost:8080/actuator/gateway/globalfilters,返回以下信息

{
    "org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@499ef98e":-1,
    "org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@24934262":-2147482648,
    "org.springframework.cloud.gateway.filter.GatewayMetricsFilter@5b051a5c":0,
    "org.springframework.cloud.gateway.filter.ForwardRoutingFilter@288214b1":2147483647,
    "org.springframework.cloud.gateway.filter.ForwardPathFilter@16eedaa6":0,
    "org.springframework.cloud.gateway.filter.NettyRoutingFilter@5fcfca62":2147483647,
    "org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@93f432e":10000,
    "org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@28501a4b":2147483646
}

從這裏能夠看到,若是隻引入 spring-cloud-starter-gateway 依賴的狀況下,默認只會實例化 8個 GlobalFilter實現類,並不是 11個,這是由於有些GlobalFilter實現類的實例化是須要必定依賴條件的,好比 LoadBalancerClientFilter ,它的依賴類是 LoadBalancerClient.class,源碼:

@Bean
@ConditionalOnBean(LoadBalancerClient.class)
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
  return new LoadBalancerClientFilter(client);
}

還有另外2個默認狀況也是沒有實例化的,分別是 WebClientHttpRoutingFilterWebClientWriteResponseFilter,由於這兩個實例化配置在源碼中被註釋掉了,上文有提到過。

總結

這篇文章只是簡單地探索了一下Spring Cloud Gateway的GlobalFilter及其默認的實現類,並未涉及到具體過濾器的做用,後續文章再一一做補充

參考

Spring Cloud Gateway官方文檔
Spring Cloud Gateway源代碼

相關文章
相關標籤/搜索