Spring source code analysis 15: the basic components of SpringCloud
SpringCloud
not just one project, but the general term for the ecosystem composed of many projects, such as
- spring-cloud-netflix : https://github.com/netflix open source components
- spring-cloud-gateway : Gateway
- spring-cloud-kubernetes : Integration kubernetes
- spring-cloud-config : distributed configuration
- spring-cloud-sleuth : distributed link tracking
- spring-cloud-openfeign : service call
But these projects all rely on a basic project spring-cloud-commons ,
spring-cloud-commons
mainly has 3 modules
spring-cloud-context
: Build a Bootstrap container and make it the parent container of the container built by the original SpringBoot program, so the way to use SpringCloud is similar to SpringBootspring-cloud-commons
: Provides an abstraction layer code for service registration and discovery, load balancing, fuse and other functions in microservices. This abstraction layer has nothing to do with the specific implementation. These functions can be implemented by different technologiesspring-cloud-loadbalancer
: A client load balancer, similar to Ribbon, used to replace Ribbon (Ribbon has entered maintenance mode)
1. spring-cloud-context
The loading of components is still loaded through the Spring Factories extension loading mechanism, which is set at 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
automatic configuration assembly - LifecycleMvcEndpointAutoConfiguration
Automatic configuration and assembly of some MVC terminal components - RefreshAutoConfiguration
Automatic assemblyspring.cloud.refresh
configuration - RefreshEndpointAutoConfiguration
Automatic configuration assembly of some refreshable contextual data terminal components - WritableEnvironmentEndpointAutoConfiguration
WritableEnvironmentEndpoint
automatic configuration assembly - BootstrapApplicationListener
Cloud application initialization - LoggingSystemShutdownListener
Log extension processing - RestartListener
Information record of application restart - PropertySourceBootstrapConfiguration
Configuration property processing during Cloud application initialization - EncryptionBootstrapConfiguration
Initial configuration for encrypted transmission - RefreshBootstrapRegistryInitializer
AddBootstrapContext
Cloud initialization context object to the application context objectApplicationContext
- TextEncryptorConfigBootstrapper
Text encryption configuration initialization - DecryptEnvironmentPostProcessor
Decryption processing of encrypted information in transmission - CachedRandomPropertySourceEnvironmentPostProcessor
Support for random value attribute sourcerandom.xxx
in configuration
The following mainly analyzes BootstrapApplicationListener
and PropertySourceBootstrapConfiguration
1.1. BootstrapApplicationListener
BootstrapApplicationListener
The main function of is to extend the loading position of the configuration file and add the loading component of 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
The main function of is for SpringCloud log, profile, configuration processing
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
This annotation is the spring-cloud-context
, used to initialize Spring Cloud components
// 通过前面介绍的 `BootstrapImportSelector` 来实现自动加载在 `spring.factories` 中使用
// `org.springframework.cloud.bootstrap.BootstrapConfiguration` 配置的类
public @interface BootstrapConfiguration {}
2. spring-cloud-commons
The loading of components is still loaded through the Spring Factories extension loading mechanism, which is set at 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
Automatic configuration and assembly ofDiscoveryClient
andLoadBalancerClient
- ReactiveCommonsClientAutoConfiguration
Automatic configuration assembly ofReactiveDiscoveryClient
andReactiveLoadBalancer
- CompositeDiscoveryClientAutoConfiguration
CompositeDiscoveryClient
automatic configuration assembly - ReactiveCompositeDiscoveryClientAutoConfiguration
ReactiveCompositeDiscoveryClient
automatic configuration assembly - SimpleDiscoveryClientAutoConfiguration
SimpleDiscoveryClient
automatic configuration assembly - SimpleReactiveDiscoveryClientAutoConfiguration
SimpleReactiveDiscoveryClient
automatic configuration assembly - CloudHypermediaAutoConfiguration
spring.cloud.hypermedia
automatic configuration assembly - AsyncLoadBalancerAutoConfiguration
Automatic configuration assembly for asynchronous load balancing - LoadBalancerAutoConfiguration
Block load balancing automatic configuration assembly - LoadBalancerBeanPostProcessorAutoConfiguration
Automatic configuration assembly for load balancing post-processing - ReactorLoadBalancerClientAutoConfiguration
Reactive load balancing automatic configuration assembly - ServiceRegistryAutoConfiguration
RegisterServiceRegistryEndpoint
- HttpClientConfiguration
Http client configuration - UtilAutoConfiguration
spring.cloud.util
automatic configuration assembly - CompatibilityVerifierAutoConfiguration
spring.cloud.compatibility-verifier
automatic configuration assembly - AutoServiceRegistrationAutoConfiguration
spring.cloud.service-registry.auto-registration
automatic configuration assembly - ResourceServerTokenRelayAutoConfiguration
spring.cloud.mvc.token-relay
automatic configuration assembly - HostInfoEnvironmentPostProcessor
Automatically addspring.cloud.client.hostname
andspring.cloud.client.ip-address
configuration attributes - CompatibilityNotMetFailureAnalyzer
Cloud error analysis and processing
2.1. @EnableDiscoveryClient & @LoadBalanced
These two annotations are the main spring-cloud-commons
@EnableDiscoveryClient
used to add the service discovery client, @LoadBalanced
used to mark the request is load balanced
// 自动实例化 `EnableDiscoveryClientImportSelector`,并载入Spring IOC容器
// 实例化 `@EnableDiscoveryClient` 注解的类,但不做实际注册、发现处理
@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {}
// 没有任何处理,只是定义注解
public @interface LoadBalanced {}
@EnableDiscoveryClient
and @LoadBalanced
have no substantial processing, just define the annotation specifications, and leave it to other components to implement
3. spring-cloud-loadbalancer
The loading of components is still loaded through the Spring Factories extension loading mechanism, which is set at 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
automatic configuration assembly - BlockingLoadBalancerClientAutoConfiguration
Block automatic configuration and assembly of load balancing clients - LoadBalancerCacheAutoConfiguration
spring.cloud.loadbalancer.cache
automatic configuration assembly - OAuth2LoadBalancerClientAutoConfiguration
spring.cloud.oauth2.load-balanced
automatic configuration assembly - LoadBalancerStatsAutoConfiguration
spring.cloud.loadbalancer.stats
automatic configuration assembly
The main analysis here is LoadBalancerAutoConfiguration
3.1. LoadBalancerAutoConfiguration
LoadBalancerAutoConfiguration
The main function is to complete spring.cloud.loadbalancer
, and instantiate the load balancing component
// 继承 `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 {
// ... 代码省略
}
Because LoadBalancerAutoConfiguration
inherits LoadBalancerClients
Comment, so take a look at LoadBalancerClients
// 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClients {
// ... 代码省略
}
Let's take a look at 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
These two annotations are the spring-cloud-loadbalancer
, which are used to add load balancing clients
// 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
// 自动处理标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClients {
// ... 代码省略
}
// 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
// 自动处理标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类
@Import(LoadBalancerClientConfigurationRegistrar.class)
public @interface LoadBalancerClient {
// ... 代码省略
}
Follow-up
For more blogs, check out https://github.com/senntyou/blogs
Author: Shen Yuzhi (@senntyou)
Copyright notice: Freely reproduced-non-commercial-non-derivative-keep the signature ( Creative Commons 3.0 License )
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。