乐趣区

关于后端:Spring-源码解析十五SpringCloud-的基础组件

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 许可证)

退出移动版