文章背景图

Spring-Cloud-Gateway 源码解析 —— 网关初始化

2026-01-29
1
-
- 分钟
|

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

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

阅读源码最好的方式,是使用 IDEA 进行调试 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

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

01-GtXXgIoPxmpFGWteYKCXPZWBbVEKhgub.png

推荐 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

组件关系交互如下图 :

04-xSIkCCNbinQGPHMWQcePJfFtCCxrLTiV.png

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 配置类。代码如下 :

@Configuration
@ConditionalOnClass(HttpClient.class)
protected static class NettyConfiguration {
	@Bean // 1.2
	@ConditionalOnMissingBean
	public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
		return HttpClient.create(options);
	}

	@Bean // 1.1
	public Consumer<? super HttpClientOptions.Builder> nettyClientOptions() {
		return opts -> {
 			opts.poolResources(PoolResources.elastic("proxy"));
			// opts.disablePool(); //TODO: why do I need this again?
		};
	}
 
	@Bean // 1.3
	public NettyRoutingFilter routingFilter(HttpClient httpClient) {
		return new NettyRoutingFilter(httpClient);
	}
 
	@Bean // 1.4
	public NettyWriteResponseFilter nettyWriteResponseFilter() {
		return new NettyWriteResponseFilter();
	}

	@Bean // 1.5 {@link org.springframework.cloud.gateway.filter.WebsocketRoutingFilter}
 	public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
		return new ReactorNettyWebSocketClient(options);
	}
}

  • 每个 @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

代码如下 :

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

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

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

@Bean // 2.4
public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient, WebSocketService webSocketService) {
	return new WebsocketRoutingFilter(webSocketClient, webSocketService);
}

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 接口的实现们。

02-ptzJnTQNNWqejvbHsZlQtCXDIPsUBsru.png

后续我们会对

GatewayFilterFactory 的实现代码做详细解析。

5.7 初始化 RoutePredicateFactory

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

03.png

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

5.8 初始化 RouteDefinitionLocator

代码如下 :

@Bean // 4.1
@ConditionalOnMissingBean
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
	return new PropertiesRouteDefinitionLocator(properties);
}

@Bean // 4.2
@ConditionalOnMissingBean(RouteDefinitionRepository.class)
public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
	return new InMemoryRouteDefinitionRepository();
}

@Bean // 4.3
@Primary // 优先被注入
public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
	return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
}


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

5.9 初始化 RouteLocator

代码如下 :

@Bean // 4.4
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
											   List<GatewayFilterFactory> GatewayFilters,
											   List<RoutePredicateFactory> predicates,
											   RouteDefinitionLocator routeDefinitionLocator) {
	return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
}

@Bean // 4.5
@Primary
public RouteLocator routeLocator(List<RouteLocator> routeLocators) {
	return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}


另外,有如下两种方式实现自定义 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);
    }
}

评论交流

文章目录