1. 程式人生 > >Spring-Cloud-Gateway原始碼分析系列| Spring-Cloud-Gateway初始化

Spring-Cloud-Gateway原始碼分析系列| Spring-Cloud-Gateway初始化

推薦 Spring Boot/Cloud 視訊:

Spring-Cloud專案使用EnableAutoConfiguration註解自動 初始化配置資訊,Spring-Cloud-Gateway同樣,Spring-Cloud-Gateway下的spring.factories(在包spring-cloud-gateway-core)如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
//依賴包的校驗配置
org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration,\
//閘道器的核心配置
org.springframework.cloud.gateway.config.GatewayAutoConfiguration,\
//負載均衡相關依賴配置資訊
org.springframework.cloud.gateway.config.GatewayLoadBalancerClientAutoConfiguration,\
//流控的依賴配置資訊
org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration,\
//註冊中心相關的依賴配置
org.springframework.cloud.gateway.discovery.GatewayDiscoveryClientAutoConfiguration

配置功能 分析配置功能前先了解下springboot常用的註解的含義

執行順序
@AutoConfigureAfter:在指定的配置類初始化後再載入
@AutoConfigureBefore:在指定的配置類初始化前載入
@AutoConfigureOrder:數越小越先初始化
條件配置
@ConditionalOnClass : classpath中存在該類時起效
@ConditionalOnMissingClass : classpath中不存在該類時起效
@ConditionalOnBean : DI容器中存在該型別Bean時起效
@ConditionalOnMissingBean : DI容器中不存在該型別Bean時起效
@ConditionalOnSingleCandidate : DI容器中該型別Bean只有一個或@Primary的只有一個時起效
@ConditionalOnExpression : SpEL表示式結果為true時
@ConditionalOnProperty : 引數設定或者值一致時起效
@ConditionalOnResource : 指定的檔案存在時起效
@ConditionalOnJndi : 指定的JNDI存在時起效
@ConditionalOnJava : 指定的Java版本存在時起效
@ConditionalOnWebApplication : Web應用環境下起效
@ConditionalOnNotWebApplication : 非Web應用環境下起效

1.GatewayClassPathWarningAutoConfiguration配置

GatewayClassPathWarningAutoConfiguration配置用於檢查專案是否正確匯入 spring-boot-starter-webflux 依賴,而不是錯誤匯入 spring-boot-starter-web 依賴,同時 GatewayClassPathWarningAutoConfiguration配置在EnableAutoConfiguration配置載入前載入 接下來我看程式碼如何實現

@Configuration
//執行順序註解
//當前註解標識需要在GatewayAutoConfiguration前載入此配置
@AutoConfigureBefore(GatewayAutoConfiguration.class)
public class GatewayClassPathWarningAutoConfiguration {
    @Configuration
    //條件判斷註解
    //classpath中存在org.springframework.web.servlet.DispatcherServlet時起效,標識專案匯入了spring-boot-starter-web包
    @ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
    protected static class SpringMvcFoundOnClasspathConfiguration {

        public SpringMvcFoundOnClasspathConfiguration() {
           //當前專案匯入了spring-boot-starter-web依賴時,列印警告日誌
            log.warn(BORDER+"Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. "+
                    "Please remove spring-boot-starter-web dependency."+BORDER);
        }

    }
    @Configuration
    //條件判斷註解
    //classpath中不存在org.springframework.web.reactive.DispatcherHandler時起效,標識專案未匯入了spring-boot-starter-webflux包
    @ConditionalOnMissingClass("org.springframework.web.reactive.DispatcherHandler")
    protected static class WebfluxMissingFromClasspathConfiguration {
        public WebfluxMissingFromClasspathConfiguration() {
      //當前專案未匯入了boot-starter-webflux依賴時,列印警告日誌
            log.warn(BORDER+"Spring Webflux is missing from the classpath, which is required for Spring Cloud Gateway at this time. "+
                    "Please add spring-boot-starter-webflux dependency."+BORDER);
        }

    }
}

2.GatewayLoadBalancerClientAutoConfiguration

GatewayLoadBalancerClientAutoConfiguration配置作用是初始化 LoadBalancerClientFilter 路由的負載均衡攔截器

@Configuration
//條件判斷註解
//classpath中存在LoadBalancerClient和RibbonAutoConfiguration和DispatcherHandler時此配置起效
@ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
//執行順序註解
@AutoConfigureAfter(RibbonAutoConfiguration.class)
public class GatewayLoadBalancerClientAutoConfiguration {
    // GlobalFilter beans
    @Bean
    //條件判斷註解
    //DI容器中存在LoadBalancerClient型別Bean時起效
    @ConditionalOnBean(LoadBalancerClient.class)
    public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
        return new LoadBalancerClientFilter(client);
    }
}

3.GatewayRedisAutoConfiguration

GatewayRedisAutoConfiguration 配置作用是初始化初始化 RedisRateLimiter 限流功能的RequestRateLimiterGatewayFilterFactory 基於 RedisRateLimiter 實現閘道器的限流功能,程式碼略

4.GatewayAutoConfiguration

GatewayAutoConfiguration配置是Spring Cloud Gateway 核心配置類,初始化如下 :

  • NettyConfiguration 底層通訊netty配置
  • GlobalFilter (AdaptCachedBodyGlobalFilter,RouteToRequestUrlFilter,ForwardRoutingFilter,ForwardPathFilter,WebsocketRoutingFilter,WeightCalculatorWebFilter等)
  • FilteringWebHandler
  • GatewayProperties
  • PrefixPathGatewayFilterFactory
  • RoutePredicateFactory
  • RouteDefinitionLocator
  • RouteLocator
  • RoutePredicateHandlerMapping 查詢匹配到 Route並進行處理
  • GatewayWebfluxEndpoint 管理閘道器的 HTTP API
@Configuration
//條件註解
//通過 spring.cloud.gateway.enabled配置閘道器的開啟與關閉
//matchIfMissing = true => 閘道器預設開啟。
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {
    @Configuration
    //當classpath中存在HttpClient起效
    @ConditionalOnClass(HttpClient.class)
    protected static class NettyConfiguration {
        .....略
    }
    
    //載入配置beans
    // ConfigurationProperty beans
    @Bean
    public GatewayProperties gatewayProperties() {
        return new GatewayProperties();
    }
    @Bean
    public SecureHeadersProperties secureHeadersProperties() {
        return new SecureHeadersProperties();
    }
    
    // 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,
        return new WebsocketRoutingFilter(webSocketClient, webSocketService, headersFilters);
    }
    @Bean
    public WeightCalculatorWebFilter weightCalculatorWebFilter(Validator validator) {
        return new WeightCalculatorWebFilter(validator);
    }
}

5.GatewayDiscoveryClientAutoConfiguration

GatewayDiscoveryClientAutoConfiguration配置的作用是初始化配置路由中的註冊發現服務資訊

@Configuration
//同4
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureBefore(GatewayAutoConfiguration.class)
@ConditionalOnClass({DispatcherHandler.class, DiscoveryClient.class})
@EnableConfigurationProperties
public class GatewayDiscoveryClientAutoConfiguration {

    @Bean
    //當classpath中存在DiscoveryClient起效
    @ConditionalOnBean(DiscoveryClient.class)
    //通過spring.cloud.gateway.discovery.locator.enabled配置註冊中心查詢的開啟與關閉
    @ConditionalOnProperty(name = "spring.cloud.gateway.discovery.locator.enabled")
    public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(
            DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
        return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
    }
}

通過自動載入初始化上述五個配置例項Spring-Cloud-Gateway就完成自身的資訊載入和初始化工作

專家推薦

“隨著微服務架構的發展,Spring Cloud 使用得越來越廣泛。馳狼課堂 Spring Boot 快速入門,Spring Boot 與Spring Cloud 整合,docker+k8s,大型電商商城等多套免費實戰教程可以幫您真正做到快速上手,將技術點切實運用到微服務專案中。”