Spring 源码解析十五:SpringCloud 的基础组件
SpringCloud
并不是只有一个项目,而是很多项目构成的生态体系总称,如
- spring-cloud-netflix: 对 https://github.com/netflix 开源组件的集成
- spring-cloud-gateway: 网关
- spring-cloud-kubernetes: 对 kubernetes 的集成
- spring-cloud-config: 分布式配置
- spring-cloud-sleuth: 分布式链路跟踪
- spring-cloud-openfeign: 服务调用
但这些项目都依赖一个基础项目 spring-cloud-commons,
spring-cloud-commons
主要有 3 个模块
spring-cloud-context
:构建一个 Bootstrap 容器,并让其成为原有的 SpringBoot 程序构建的容器的父容器,所以使用 SpringCloud 的方式与 SpringBoot 是差不多的spring-cloud-commons
:对微服务中的服务注册与发现、负载均衡、熔断器等功能提供一个抽象层代码,这个抽象层与具体的实现无关,这些功能可以采用不同的技术去实现spring-cloud-loadbalancer
:一个客户端负载均衡器,类似于 Ribbon,用于替换 Ribbon(Ribbon 已经进入维护模式)
1. spring-cloud-context
组件的加载仍然是通过 Spring Factories 扩展加载机制加载的,定在 spring.factories
# 属性自动装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration
# 应用监听器
org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener
# Spring Cloud 初始化组件
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\
org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
# Spring Boot 初始化注册
org.springframework.boot.BootstrapRegistryInitializer=\
org.springframework.cloud.bootstrap.RefreshBootstrapRegistryInitializer,\
org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper
# 环境后置处理
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.bootstrap.encrypt.DecryptEnvironmentPostProcessor,\
org.springframework.cloud.util.random.CachedRandomPropertySourceEnvironmentPostProcessor
ConfigurationPropertiesRebinderAutoConfiguration
ConfigurationPropertiesRebinder
的自动配置装配LifecycleMvcEndpointAutoConfiguration 一些 MVC 终端组件的自动配置装配
RefreshAutoConfiguration 自动装配
spring.cloud.refresh
配置RefreshEndpointAutoConfiguration 一些可刷新上下文数据终端组件的自动配置装配
WritableEnvironmentEndpointAutoConfiguration
WritableEnvironmentEndpoint
的自动配置装配BootstrapApplicationListener Cloud 应用初始化
RestartListener 应用重新启动的信息记录
PropertySourceBootstrapConfiguration Cloud 应用初始化时的配置属性处理
EncryptionBootstrapConfiguration 对加密传输的初始化配置
RefreshBootstrapRegistryInitializer 向应用上下文对象
ApplicationContext
添加BootstrapContext
Cloud 初始化上下文对象TextEncryptorConfigBootstrapper 文本加密配置初始化
DecryptEnvironmentPostProcessor 传输中加密信息的解密处理
CachedRandomPropertySourceEnvironmentPostProcessor 对配置中随机值属性源
random.xxx
的支持
下面主要解析一下 BootstrapApplicationListener
与 PropertySourceBootstrapConfiguration
1.1. BootstrapApplicationListener
BootstrapApplicationListener 的主要功能是扩展配置文件的加载位置、添加 spring.factories
的加载组件
public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
// ... 代码省略
// 初始化上下文环境
context = bootstrapServiceContext(environment, event.getSpringApplication(), configName);
// ... 代码省略
}
// 初始化上下文环境
private ConfigurableApplicationContext bootstrapServiceContext(ConfigurableEnvironment environment,
final SpringApplication application, String configName) {
// ... 代码省略
String configLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.location:}");
String configAdditionalLocation = environment
.resolvePlaceholders("${spring.cloud.bootstrap.additional-location:}");
Map<String, Object> bootstrapMap = new HashMap<>();
// 扩展 spring.cloud.bootstrap.location 配置到 spring.config.location 中
if (StringUtils.hasText(configLocation)) {
bootstrapMap.put("spring.config.location", configLocation);
}
// 扩展 spring.cloud.bootstrap.additional-location 配置到 spring.config.additional-location 中
if (StringUtils.hasText(configAdditionalLocation)) {
bootstrapMap.put("spring.config.additional-location", configAdditionalLocation);
}
// ... 代码省略
// 通过 BootstrapImportSelector 添加 `spring.factories` 的加载组件 `org.springframework.cloud.bootstrap.BootstrapConfiguration`
builder.sources(BootstrapImportSelectorConfiguration.class);
}
}
public class BootstrapImportSelector implements EnvironmentAware, DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// ... 代码省略
// 通过 SpringFactoriesLoader 加载 `org.springframework.cloud.bootstrap.BootstrapConfiguration` 指定的组件
List<String> names = new ArrayList<>(
SpringFactoriesLoader.loadFactoryNames(BootstrapConfiguration.class, classLoader));
// 配置中的 spring.cloud.bootstrap.sources 也当做 BootstrapConfiguration 组件加载
names.addAll(Arrays.asList(StringUtils
.commaDelimitedListToStringArray(this.environment.getProperty("spring.cloud.bootstrap.sources", ""))));
// ... 代码省略
}
}
1.2. PropertySourceBootstrapConfiguration
PropertySourceBootstrapConfiguration 的主要功能是针对 SpringCloud 的日志、Profile、配置处理
public class PropertySourceBootstrapConfiguration
implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
// ... 代码省略
MutablePropertySources propertySources = environment.getPropertySources();
// ... 代码省略
// 加载自定义的配置加载处理,spring-cloud-config 的分布式配置功能就有赖于此
insertPropertySources(propertySources, composite);
// 处理 logging.config 指定的日志配置
String logConfig = environment.resolvePlaceholders("${logging.config:}");
LogFile logFile = LogFile.get(environment);
reinitializeLoggingSystem(environment, logConfig, logFile);
// 设置日志记录等级
setLogLevels(applicationContext, environment);
// 处理 spring.profiles.active 激活的环境
handleIncludedProfiles(environment);
}
}
1.3. @BootstrapConfiguration
这个注解是 spring-cloud-context
主要的注解,用于初始化 Spring Cloud 组件
// 通过前面介绍的 `BootstrapImportSelector` 来实现自动加载在 `spring.factories` 中使用
// `org.springframework.cloud.bootstrap.BootstrapConfiguration` 配置的类
public @interface BootstrapConfiguration {}
2. spring-cloud-commons
组件的加载仍然是通过 Spring Factories 扩展加载机制加载的,定在 spring.factories
# 属性自动装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.client.CommonsClientAutoConfiguration,\
org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration,\
org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\
org.springframework.cloud.commons.httpclient.HttpClientConfiguration,\
org.springframework.cloud.commons.util.UtilAutoConfiguration,\
org.springframework.cloud.configuration.CompatibilityVerifierAutoConfiguration,\
org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration,\
org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration
# 环境后置处理
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.client.HostInfoEnvironmentPostProcessor
# 错误分析
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.cloud.configuration.CompatibilityNotMetFailureAnalyzer
CommonsClientAutoConfiguration
DiscoveryClient
与LoadBalancerClient
的自动配置装配ReactiveCommonsClientAutoConfiguration
ReactiveDiscoveryClient
与ReactiveLoadBalancer
的自动配置装配CompositeDiscoveryClientAutoConfiguration
CompositeDiscoveryClient
的自动配置装配ReactiveCompositeDiscoveryClientAutoConfiguration
ReactiveCompositeDiscoveryClient
的自动配置装配SimpleDiscoveryClientAutoConfiguration
SimpleDiscoveryClient
的自动配置装配SimpleReactiveDiscoveryClientAutoConfiguration
SimpleReactiveDiscoveryClient
的自动配置装配CloudHypermediaAutoConfiguration
spring.cloud.hypermedia
的自动配置装配AsyncLoadBalancerAutoConfiguration 异步负载均衡的自动配置装配
LoadBalancerAutoConfiguration 阻塞负载均衡的自动配置装配
LoadBalancerBeanPostProcessorAutoConfiguration 负载均衡后置处理的自动配置装配
ReactorLoadBalancerClientAutoConfiguration Reactive 负载均衡的自动配置装配
ServiceRegistryAutoConfiguration 注册
ServiceRegistryEndpoint
HttpClientConfiguration Http 客户端配置
UtilAutoConfiguration
spring.cloud.util
的自动配置装配CompatibilityVerifierAutoConfiguration
spring.cloud.compatibility-verifier
的自动配置装配AutoServiceRegistrationAutoConfiguration
spring.cloud.service-registry.auto-registration
的自动配置装配ResourceServerTokenRelayAutoConfiguration
spring.cloud.mvc.token-relay
的自动配置装配HostInfoEnvironmentPostProcessor 自动加上
spring.cloud.client.hostname
与spring.cloud.client.ip-address
配置属性CompatibilityNotMetFailureAnalyzer Cloud 错误分析处理
2.1. @EnableDiscoveryClient & @LoadBalanced
这两个注解是 spring-cloud-commons
主要的注解,@EnableDiscoveryClient
用于添加服务发现客户端,@LoadBalanced
用于标志请求是负载均衡的
// 自动实例化 `EnableDiscoveryClientImportSelector`,并载入Spring IOC容器
// 实例化 `@EnableDiscoveryClient` 注解的类,但不做实际注册、发现处理
@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {}
// 没有任何处理,只是定义注解
public @interface LoadBalanced {}
@EnableDiscoveryClient
与 @LoadBalanced
都没有实质上的处理,只是定义好注解规范,留待其他组件实现
3. spring-cloud-loadbalancer
组件的加载仍然是通过 Spring Factories 扩展加载机制加载的,定在 spring.factories
# 属性自动装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration,\
org.springframework.cloud.loadbalancer.security.OAuth2LoadBalancerClientAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.LoadBalancerStatsAutoConfiguration
- LoadBalancerAutoConfiguration
spring.cloud.loadbalancer
的自动配置装配 - BlockingLoadBalancerClientAutoConfiguration 阻塞负载均衡客户端的自动配置装配
- LoadBalancerCacheAutoConfiguration
spring.cloud.loadbalancer.cache
的自动配置装配 - OAuth2LoadBalancerClientAutoConfiguration
spring.cloud.oauth2.load-balanced
的自动配置装配 - LoadBalancerStatsAutoConfiguration
spring.cloud.loadbalancer.stats
的自动配置装配
这里主要解析一下 LoadBalancerAutoConfiguration
3.1. LoadBalancerAutoConfiguration
LoadBalancerAutoConfiguration 的主要功能是完成 spring.cloud.loadbalancer
的自动配置装配,并实例化负载均衡组件
// 继承 `LoadBalancerClients` 的注解
@LoadBalancerClients
// 自动装配 `spring.cloud.loadbalancer` 配置
@EnableConfigurationProperties(LoadBalancerProperties.class)
// 使用 `spring.cloud.loadbalancer.enabled` 来启动此组件
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true)
public class LoadBalancerAutoConfiguration {
// ... 代码省略
}
因为 LoadBalancerAutoConfiguration
继承了 LoadBalancerClients 的注解,所以来看看 LoadBalancerClients
// 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClients {
// ... 代码省略
}
再来看看 LoadBalancerClientConfigurationRegistrar
public class LoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 获取 @LoadBalancerClients 注解
Map<String, Object> attrs = metadata.getAnnotationAttributes(LoadBalancerClients.class.getName(), true);
if (attrs != null && attrs.containsKey("value")) {
// 获取注解中 value 指定的值,并注册bean组件定义
AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
for (AnnotationAttributes client : clients) {
registerClientConfiguration(registry, getClientName(client), client.get("configuration"));
}
}
// ... 代码省略
// 获取 @LoadBalancerClient 注解
Map<String, Object> client = metadata.getAnnotationAttributes(LoadBalancerClient.class.getName(), true);
// 获取注解中 name/value 指定的值,并注册bean组件定义
String name = getClientName(client);
if (name != null) {
registerClientConfiguration(registry, name, client.get("configuration"));
}
}
}
3.2. @LoadBalancerClients & @LoadBalancerClient
这两个注解是 spring-cloud-loadbalancer
主要的注解,用于添加负载均衡客户端
// 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
// 自动处理标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClients {
// ... 代码省略
}
// 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
// 自动处理标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClient {
// ... 代码省略
}
后续
更多博客,查看 https://github.com/deepraining/blogs
版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)