⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/init/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Spring-Cloud-Gateway 2.0.X M4


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

阅读源码最好的方式,是使用 IDEA 进行调试 Spring Cloud Gateway 源码,不然会一脸懵逼。

胖友可以点击「芋道源码」扫码关注,回复 git019 关键字
获得艿艿添加了中文注释的 Spring Cloud Gateway 源码地址。

阅读源码很孤单,加入源码交流群,一起坚持!

1. 概述

本文主要分享 Spring Cloud Gateway 启动初始化的过程

在初始化的过程中,涉及到的组件会较多,本文不会细说,留到后面每篇文章针对每个组件详细述说。

那么这有什么意义呢?先对 Spring Cloud Gateway 内部的组件有整体的印象。


在官方提供的实例项目 spring-cloud-gateway-sample ,我们看到 GatewaySampleApplication 上有 @EnableAutoConfiguration 注解。因为该项目导入了 spring-cloud-gateway-core 依赖库,它会扫描 Spring Cloud Gateway 的配置。

org.springframework.cloud.gateway.config 包下,我们可以看到四个配置类 :

  • GatewayAutoConfiguration
  • GatewayClassPathWarningAutoConfiguration
  • GatewayLoadBalancerClientAutoConfiguration
  • GatewayRedisAutoConfiguration

它们的初始化顺序如下图 :


推荐 Spring Cloud 书籍

2. GatewayClassPathWarningAutoConfiguration

Spring Cloud Gateway 2.x 基于 Spring WebFlux 实现。

org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration ,用于检查项目是否正确导入 spring-boot-starter-webflux 依赖,而不是错误导入 spring-boot-starter-web 依赖。

点击链接 链接 查看 GatewayClassPathWarningAutoConfiguration 的代码实现。

3. GatewayLoadBalancerClientAutoConfiguration

org.springframework.cloud.gateway.config.GatewayLoadBalancerClientAutoConfiguration ,初始化 LoadBalancerClientFilter ,点击 链接 查看代码。

《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡》 详细解析 LoadBalancerClientFilter 的代码实现。

4. GatewayRedisAutoConfiguration

org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration ,初始化 RedisRateLimiter 。

RequestRateLimiterGatewayFilterFactory 基于 RedisRateLimiter 实现网关的限流功能,在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.10) 之 RequestRateLimiterGatewayFilterFactory 请求限流》 详细解析相关的代码实现。

5. GatewayAutoConfiguration

org.springframework.cloud.gateway.config.GatewayAutoConfiguration ,Spring Cloud Gateway 核心配置类,初始化如下 :

  • NettyConfiguration
  • GlobalFilter
  • FilteringWebHandler
  • GatewayProperties
  • PrefixPathGatewayFilterFactory
  • RoutePredicateFactory
  • RouteDefinitionLocator
  • RouteLocator
  • RoutePredicateHandlerMapping
  • GatewayWebfluxEndpoint

组件关系交互如下图 :

5.1 网关的开启与关闭

从 GatewayAutoConfiguration 上的注解 @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true) ,我们可以看出 :

  • 通过 spring.cloud.gateway.enabled 配置网关的开启与关闭。
  • matchIfMissing = true => 网关默认开启

5.2 初始化 NettyConfiguration

org.springframework.cloud.gateway.config.NettyConfiguration ,Netty 配置类。代码如下 :

 1: @Configuration
2: @ConditionalOnClass(HttpClient.class)
3: protected static class NettyConfiguration {
4: @Bean // 1.2
5: @ConditionalOnMissingBean
6: public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
7: return HttpClient.create(options);
8: }
9:
10: @Bean // 1.1
11: public Consumer<? super HttpClientOptions.Builder> nettyClientOptions() {
12: return opts -> {
13: opts.poolResources(PoolResources.elastic("proxy"));
14: // opts.disablePool(); //TODO: why do I need this again?
15: };
16: }
17:
18: @Bean // 1.3
19: public NettyRoutingFilter routingFilter(HttpClient httpClient) {
20: return new NettyRoutingFilter(httpClient);
21: }
22:
23: @Bean // 1.4
24: public NettyWriteResponseFilter nettyWriteResponseFilter() {
25: return new NettyWriteResponseFilter();
26: }
27:
28: @Bean // 1.5 {@link org.springframework.cloud.gateway.filter.WebsocketRoutingFilter}
29: public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
30: return new ReactorNettyWebSocketClient(options);
31: }
32: }

  • 每个 @Bean 注解后的数字为 Bean 的初始化顺序
  • 第 10 至 16 行 :创建一个类型为 java.util.Objects.Consumer 的 Bean 对象。该 Consumer 会将传入类型为 reactor.ipc.netty.options.HttpClientOptions.Builder 的参数 opts ,设置 optspoolResources 属性。
    • 调用 PoolResources.elastic("proxy") 方法,创建 name 属性为 "proxy"reactor.ipc.netty.resources.PoolResources 。其中 "proxy" 用于实际使用时,打印日志的标记
  • 第 4 至 8 行 :创建一个类型为 reactor.ipc.netty.http.client.HttpClient 的 Bean 对象。该 HttpClient 使用 Netty 实现的 Client 。
  • 第 18 至 21 行 :使用 HttpClient Bean ,创建一个类型为 org.springframework.cloud.gateway.filter.NettyRoutingFilter 的 Bean 对象。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》 详细解析 NettyRoutingFilter 的代码实现。
  • 第 23 至 26 行 :创建一个类型为 org.springframework.cloud.gateway.filter.NettyWriteResponseFilter 的 Bean 对象。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》 详细解析 NettyWriteResponseFilter 的代码实现。
  • 第 28 至 31 行 :创建一个类型为 org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient 的 Bean 对象,用于下文 WebsocketRoutingFilter 的 Bean 对象创建。

5.3 初始化 GlobalFilter

代码如下 :

 1: @Bean // 2.1
2: public RouteToRequestUrlFilter routeToRequestUrlFilter() {
3: return new RouteToRequestUrlFilter();
4: }
5:
6: @Bean // 2.2
7: @ConditionalOnBean(DispatcherHandler.class)
8: public ForwardRoutingFilter forwardRoutingFilter(DispatcherHandler dispatcherHandler) {
9: return new ForwardRoutingFilter(dispatcherHandler);
10: }
11:
12: @Bean // 2.3
13: public WebSocketService webSocketService() {
14: return new HandshakeWebSocketService();
15: }
16:
17: @Bean // 2.4
18: public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient, WebSocketService webSocketService) {
19: return new WebsocketRoutingFilter(webSocketClient, webSocketService);
20: }

5.4 初始化 FilteringWebHandler

当所有 org.springframework.cloud.gateway.filter.GlobalFilter 初始化完成时( 包括上面的 NettyRoutingFilter / NettyWriteResponseFilter ),创建一个类型为 org.springframework.cloud.gateway.handler.FilteringWebHandler 的 Bean 对象,代码如下 :

@Bean // 2.6
public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
return new FilteringWebHandler(globalFilters);
}

5.5 初始化 GatewayProperties

创建一个类型为 org.springframework.cloud.gateway.config.GatewayProperties 的 Bean 对象,用于加载配置文件配置的 RouteDefinition / FilterDefinition 。代码如下 :

@Bean // 2.7
public GatewayProperties gatewayProperties() {
return new GatewayProperties();
}

5.6 初始化 PrefixPathGatewayFilterFactory

链接 的【第 288 至 372 行】,创建 org.springframework.cloud.gateway.filter.factory 包下的 org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory 接口的实现们。

后续我们会对每个 GatewayFilterFactory 的实现代码做详细解析。

5.7 初始化 RoutePredicateFactory

链接 的【第 236 至 284 行】,创建 org.springframework.cloud.gateway.handler.predicate 包下的 org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory 接口的实现们。

后续我们会对每个 RoutePredicateFactory 的实现代码做详细解析。

5.8 初始化 RouteDefinitionLocator

代码如下 :

 1: @Bean // 4.1
2: @ConditionalOnMissingBean
3: public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
4: return new PropertiesRouteDefinitionLocator(properties);
5: }
6:
7: @Bean // 4.2
8: @ConditionalOnMissingBean(RouteDefinitionRepository.class)
9: public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
10: return new InMemoryRouteDefinitionRepository();
11: }
12:
13: @Bean // 4.3
14: @Primary // 优先被注入
15: public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
16: return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
17: }


org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator ,基于 DiscoveryClient 注册发现的 RouteDefinitionLocator 实现类,需要手动引入配置,点击 链接 查看。在 《Spring-Cloud-Gateway 源码解析 —— 路由(1.4)之 DiscoveryClientRouteDefinitionLocator 注册中心》 详细解析 DiscoveryClientRouteDefinitionLocator 的代码实现。

5.9 初始化 RouteLocator

代码如下 :

 1: @Bean // 4.4
2: public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
3: List<GatewayFilterFactory> GatewayFilters,
4: List<RoutePredicateFactory> predicates,
5: RouteDefinitionLocator routeDefinitionLocator) {
6: return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
7: }
8:
9: @Bean // 4.5
10: @Primary
11: public RouteLocator routeLocator(List<RouteLocator> routeLocators) {
12: return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
13: }


另外,有如下两种方式实现自定义 RouteLocator :

  • 使用 Routes#locator()#build() 方法,创建 RouteLocator ,例子代码如下 :

    @Bean
    public RouteLocator customRouteLocator() {
    //@formatter:off
    return Routes.locator()
    .route("test")
    .predicate(host("**.abc.org").and(path("/image/png")))
    .addResponseHeader("X-TestHeader", "foobar")
    .uri("http://httpbin.org:80")
    .route("test2")
    .predicate(path("/image/webp"))
    .add(addResponseHeader("X-AnotherHeader", "baz"))
    .uri("http://httpbin.org:80")
    .build();
    ////@formatter:on
    }

  • 使用 RouteLocatorDsl#gateway() 方法,创建 RouteLocator ,该方式使用 Kotlin 实现例子代码如下 :

    @Configuration
    class AdditionalRoutes {

    @Bean
    fun additionalRouteLocator(): RouteLocator = gateway {
    route(id = "test-kotlin") {
    uri("http://httpbin.org:80")
    predicate(host("kotlin.abc.org") and path("/image/png"))
    add(addResponseHeader("X-TestHeader", "foobar"))
    }
    }

    }

5.10 初始化 RoutePredicateHandlerMapping

创建一个类型为 org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping 的 Bean 对象,用于查找匹配到 Route ,并进行处理。代码如下 :

@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator);
}

5.11 初始化 GatewayWebfluxEndpoint

创建一个类型为 org.springframework.cloud.gateway.actuate.GatewayWebfluxEndpoint 的 Bean 对象,提供管理网关的 HTTP API ,代码如下 :

@ManagementContextConfiguration
@ConditionalOnProperty(value = "management.gateway.enabled", matchIfMissing = true)
@ConditionalOnClass(Health.class)
protected static class GatewayActuatorConfiguration {

@Bean
public GatewayWebfluxEndpoint gatewayWebfluxEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,

List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
return new GatewayWebfluxEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
}
}

666. 彩蛋

知识星球

是不是内心里面有种感觉,“劳资看了一堆构造函数”?

嘿嘿嘿,后面咱一篇一篇走起!

胖友,分享一波朋友圈可好!

文章目录
  1. 1. 1. 概述
  2. 2. 2. GatewayClassPathWarningAutoConfiguration
  3. 3. 3. GatewayLoadBalancerClientAutoConfiguration
  4. 4. 4. GatewayRedisAutoConfiguration
  5. 5. 5. GatewayAutoConfiguration
    1. 5.1. 5.1 网关的开启与关闭
    2. 5.2. 5.2 初始化 NettyConfiguration
    3. 5.3. 5.3 初始化 GlobalFilter
    4. 5.4. 5.4 初始化 FilteringWebHandler
    5. 5.5. 5.5 初始化 GatewayProperties
    6. 5.6. 5.6 初始化 PrefixPathGatewayFilterFactory
    7. 5.7. 5.7 初始化 RoutePredicateFactory
    8. 5.8. 5.8 初始化 RouteDefinitionLocator
    9. 5.9. 5.9 初始化 RouteLocator
    10. 5.10. 5.10 初始化 RoutePredicateHandlerMapping
    11. 5.11. 5.11 初始化 GatewayWebfluxEndpoint
  6. 6. 666. 彩蛋