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 利用初始化
  • LoggingSystemShutdownListener
    日志扩大解决
  • RestartListener
    利用重新启动的信息记录
  • PropertySourceBootstrapConfiguration
    Cloud 利用初始化时的配置属性解决
  • EncryptionBootstrapConfiguration
    对加密传输的初始化配置
  • RefreshBootstrapRegistryInitializer
    向利用上下文对象 ApplicationContext 增加 BootstrapContext Cloud 初始化上下文对象
  • TextEncryptorConfigBootstrapper
    文本加密配置初始化
  • DecryptEnvironmentPostProcessor
    传输中加密信息的解密解决
  • CachedRandomPropertySourceEnvironmentPostProcessor
    对配置中随机值属性源 random.xxx 的反对

上面次要解析一下 BootstrapApplicationListenerPropertySourceBootstrapConfiguration

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 组件

BootstrapConfiguration

// 通过后面介绍的 `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
    DiscoveryClientLoadBalancerClient 的主动配置拆卸
  • ReactiveCommonsClientAutoConfiguration
    ReactiveDiscoveryClientReactiveLoadBalancer 的主动配置拆卸
  • 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.hostnamespring.cloud.client.ip-address配置属性
  • CompatibilityNotMetFailureAnalyzer
    Cloud 谬误剖析解决

2.1. @EnableDiscoveryClient & @LoadBalanced

这两个注解是 spring-cloud-commons 次要的注解,@EnableDiscoveryClient 用于增加服务发现客户端,@LoadBalanced 用于标记申请是负载平衡的

EnableDiscoveryClient

// 主动实例化 `EnableDiscoveryClientImportSelector`,并载入Spring IOC容器// 实例化 `@EnableDiscoveryClient` 注解的类,但不做理论注册、发现解决@Import(EnableDiscoveryClientImportSelector.class)public @interface EnableDiscoveryClient {}

LoadBalanced

// 没有任何解决,只是定义注解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 次要的注解,用于增加负载平衡客户端

LoadBalancerClients

// 主动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器// 主动解决标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类@Import(LoadBalancerClientConfigurationRegistrar.class)public @interface LoadBalancerClients {    // ... 代码省略}

LoadBalancerClient

// 主动实例化 `LoadBalancerClientConfigurationRegistrar`,并载入Spring IOC容器// 主动解决标记有 `@LoadBalancerClients` & `@LoadBalancerClient` 注解的类@Import(LoadBalancerClientConfigurationRegistrar.class)public @interface LoadBalancerClient {    // ... 代码省略}

后续

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

作者:深予之 (@senntyou)

版权申明:自在转载-非商用-非衍生-放弃署名(创意共享 3.0 许可证)