Spring 源码解析十五:SpringCloud 的基础组件

x33g5p2x  于2022-02-11 发布在 Spring  
字(13.1k)|赞(0)|评价(0)|浏览(713)

SpringCloud 并不是只有一个项目,而是很多项目构成的生态体系总称,如

但这些项目都依赖一个基础项目 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

  1. # 属性自动装配
  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  3. org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
  4. org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\
  5. org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
  6. org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
  7. org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration
  8. # 应用监听器
  9. org.springframework.context.ApplicationListener=\
  10. org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
  11. org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
  12. org.springframework.cloud.context.restart.RestartListener
  13. # Spring Cloud 初始化组件
  14. org.springframework.cloud.bootstrap.BootstrapConfiguration=\
  15. org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\
  16. org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\
  17. org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
  18. org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
  19. # Spring Boot 初始化注册
  20. org.springframework.boot.BootstrapRegistryInitializer=\
  21. org.springframework.cloud.bootstrap.RefreshBootstrapRegistryInitializer,\
  22. org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper
  23. # 环境后置处理
  24. org.springframework.boot.env.EnvironmentPostProcessor=\
  25. org.springframework.cloud.bootstrap.encrypt.DecryptEnvironmentPostProcessor,\
  26. org.springframework.cloud.util.random.CachedRandomPropertySourceEnvironmentPostProcessor

下面主要解析一下 BootstrapApplicationListenerPropertySourceBootstrapConfiguration

1.1. BootstrapApplicationListener

BootstrapApplicationListener
的主要功能是扩展配置文件的加载位置、添加 spring.factories 的加载组件

  1. public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
  2. @Override
  3. public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
  4. // ... 代码省略
  5. // 初始化上下文环境
  6. context = bootstrapServiceContext(environment, event.getSpringApplication(), configName);
  7. // ... 代码省略
  8. }
  9. // 初始化上下文环境
  10. private ConfigurableApplicationContext bootstrapServiceContext(ConfigurableEnvironment environment,
  11. final SpringApplication application, String configName) {
  12. // ... 代码省略
  13. String configLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.location:}");
  14. String configAdditionalLocation = environment
  15. .resolvePlaceholders("${spring.cloud.bootstrap.additional-location:}");
  16. Map<String, Object> bootstrapMap = new HashMap<>();
  17. // 扩展 spring.cloud.bootstrap.location 配置到 spring.config.location 中
  18. if (StringUtils.hasText(configLocation)) {
  19. bootstrapMap.put("spring.config.location", configLocation);
  20. }
  21. // 扩展 spring.cloud.bootstrap.additional-location 配置到 spring.config.additional-location 中
  22. if (StringUtils.hasText(configAdditionalLocation)) {
  23. bootstrapMap.put("spring.config.additional-location", configAdditionalLocation);
  24. }
  25. // ... 代码省略
  26. // 通过 BootstrapImportSelector 添加 `spring.factories` 的加载组件 `org.springframework.cloud.bootstrap.BootstrapConfiguration`
  27. builder.sources(BootstrapImportSelectorConfiguration.class);
  28. }
  29. }
  1. public class BootstrapImportSelector implements EnvironmentAware, DeferredImportSelector {
  2. @Override
  3. public String[] selectImports(AnnotationMetadata annotationMetadata) {
  4. // ... 代码省略
  5. // 通过 SpringFactoriesLoader 加载 `org.springframework.cloud.bootstrap.BootstrapConfiguration` 指定的组件
  6. List<String> names = new ArrayList<>(
  7. SpringFactoriesLoader.loadFactoryNames(BootstrapConfiguration.class, classLoader));
  8. // 配置中的 spring.cloud.bootstrap.sources 也当做 BootstrapConfiguration 组件加载
  9. names.addAll(Arrays.asList(StringUtils
  10. .commaDelimitedListToStringArray(this.environment.getProperty("spring.cloud.bootstrap.sources", ""))));
  11. // ... 代码省略
  12. }
  13. }

1.2. PropertySourceBootstrapConfiguration

PropertySourceBootstrapConfiguration
的主要功能是针对 SpringCloud 的日志、Profile、配置处理

  1. public class PropertySourceBootstrapConfiguration
  2. implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
  3. @Override
  4. public void initialize(ConfigurableApplicationContext applicationContext) {
  5. // ... 代码省略
  6. MutablePropertySources propertySources = environment.getPropertySources();
  7. // ... 代码省略
  8. // 加载自定义的配置加载处理,spring-cloud-config 的分布式配置功能就有赖于此
  9. insertPropertySources(propertySources, composite);
  10. // 处理 logging.config 指定的日志配置
  11. String logConfig = environment.resolvePlaceholders("${logging.config:}");
  12. LogFile logFile = LogFile.get(environment);
  13. reinitializeLoggingSystem(environment, logConfig, logFile);
  14. // 设置日志记录等级
  15. setLogLevels(applicationContext, environment);
  16. // 处理 spring.profiles.active 激活的环境
  17. handleIncludedProfiles(environment);
  18. }
  19. }

1.3. @BootstrapConfiguration

这个注解是 spring-cloud-context 主要的注解,用于初始化 Spring Cloud 组件

BootstrapConfiguration

  1. // 通过前面介绍的 `BootstrapImportSelector` 来实现自动加载在 `spring.factories` 中使用
  2. // `org.springframework.cloud.bootstrap.BootstrapConfiguration` 配置的类
  3. public @interface BootstrapConfiguration {}

2. spring-cloud-commons

组件的加载仍然是通过 Spring Factories 扩展加载机制加载的,定在 spring.factories

  1. # 属性自动装配
  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  3. org.springframework.cloud.client.CommonsClientAutoConfiguration,\
  4. org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration,\
  5. org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\
  6. org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration,\
  7. org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,\
  8. org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration,\
  9. org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration,\
  10. org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,\
  11. org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
  12. org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration,\
  13. org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration,\
  14. org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\
  15. org.springframework.cloud.commons.httpclient.HttpClientConfiguration,\
  16. org.springframework.cloud.commons.util.UtilAutoConfiguration,\
  17. org.springframework.cloud.configuration.CompatibilityVerifierAutoConfiguration,\
  18. org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration,\
  19. org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration
  20. # 环境后置处理
  21. org.springframework.boot.env.EnvironmentPostProcessor=\
  22. org.springframework.cloud.client.HostInfoEnvironmentPostProcessor
  23. # 错误分析
  24. org.springframework.boot.diagnostics.FailureAnalyzer=\
  25. org.springframework.cloud.configuration.CompatibilityNotMetFailureAnalyzer

2.1. @EnableDiscoveryClient & @LoadBalanced

这两个注解是 spring-cloud-commons 主要的注解,@EnableDiscoveryClient 用于添加服务发现客户端,@LoadBalanced 用于标志请求是负载均衡的

EnableDiscoveryClient

  1. // 自动实例化 `EnableDiscoveryClientImportSelector`,并载入Spring IOC容器
  2. // 实例化 `@EnableDiscoveryClient` 注解的类,但不做实际注册、发现处理
  3. @Import(EnableDiscoveryClientImportSelector.class)
  4. public @interface EnableDiscoveryClient {}

LoadBalanced

  1. // 没有任何处理,只是定义注解
  2. public @interface LoadBalanced {}

@EnableDiscoveryClient@LoadBalanced 都没有实质上的处理,只是定义好注解规范,留待其他组件实现

3. spring-cloud-loadbalancer

组件的加载仍然是通过 Spring Factories 扩展加载机制加载的,定在 spring.factories

  1. # 属性自动装配
  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  3. org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration,\
  4. org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration,\
  5. org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration,\
  6. org.springframework.cloud.loadbalancer.security.OAuth2LoadBalancerClientAutoConfiguration,\
  7. org.springframework.cloud.loadbalancer.config.LoadBalancerStatsAutoConfiguration

这里主要解析一下 LoadBalancerAutoConfiguration

3.1. LoadBalancerAutoConfiguration

LoadBalancerAutoConfiguration
的主要功能是完成 spring.cloud.loadbalancer 的自动配置装配,并实例化负载均衡组件

  1. // 继承 `LoadBalancerClients` 的注解
  2. @LoadBalancerClients
  3. // 自动装配 `spring.cloud.loadbalancer` 配置
  4. @EnableConfigurationProperties(LoadBalancerProperties.class)
  5. // 使用 `spring.cloud.loadbalancer.enabled` 来启动此组件
  6. @ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true)
  7. public class LoadBalancerAutoConfiguration {
  8. // ... 代码省略
  9. }

因为 LoadBalancerAutoConfiguration 继承了 LoadBalancerClients
的注解,所以来看看 LoadBalancerClients

  1. // 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
  2. @Import(LoadBalancerClientConfigurationRegistrar.class)
  3. public @interface LoadBalancerClients {
  4. // ... 代码省略
  5. }

再来看看 LoadBalancerClientConfigurationRegistrar

  1. public class LoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
  2. @Override
  3. public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
  4. // 获取 @LoadBalancerClients 注解
  5. Map<String, Object> attrs = metadata.getAnnotationAttributes(LoadBalancerClients.class.getName(), true);
  6. if (attrs != null && attrs.containsKey("value")) {
  7. // 获取注解中 value 指定的值,并注册bean组件定义
  8. AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
  9. for (AnnotationAttributes client : clients) {
  10. registerClientConfiguration(registry, getClientName(client), client.get("configuration"));
  11. }
  12. }
  13. // ... 代码省略
  14. // 获取 @LoadBalancerClient 注解
  15. Map<String, Object> client = metadata.getAnnotationAttributes(LoadBalancerClient.class.getName(), true);
  16. // 获取注解中 name/value 指定的值,并注册bean组件定义
  17. String name = getClientName(client);
  18. if (name != null) {
  19. registerClientConfiguration(registry, name, client.get("configuration"));
  20. }
  21. }
  22. }

3.2. @LoadBalancerClients & @LoadBalancerClient

这两个注解是 spring-cloud-loadbalancer 主要的注解,用于添加负载均衡客户端

LoadBalancerClients

  1. // 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
  2. // 自动处理标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类
  3. @Import(LoadBalancerClientConfigurationRegistrar.class)
  4. public @interface LoadBalancerClients {
  5. // ... 代码省略
  6. }

LoadBalancerClient

  1. // 自动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器
  2. // 自动处理标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类
  3. @Import(LoadBalancerClientConfigurationRegistrar.class)
  4. public @interface LoadBalancerClient {
  5. // ... 代码省略
  6. }

后续

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证

相关文章