spring cloud context 介绍


Spring Cloud 核心库简介

Spring Cloud Commons工程提供了两个库功能:Spring Cloud ContextSpring Cloud CommonsSpring Cloud Context为Spring Cloud应用程序的ApplicationContextbootstrap引导程序上下文,encryption加密,refreshScope刷新作用域和环境端点)提供实用程序和特殊服务。 Spring Cloud Commons是在不同的Spring Cloud实现中使用的一组抽象和通用类(例如,Spring Cloud NetflixSpring Cloud Consul以及现在的Spring cloud Alibaba)。

Spring Cloud Context

  • Bootstrap Context
  • TextEncryptor 组件
  • Refresh Scope(当bean的属性在外部被修改时,bean会被重新创建而应用不需要重启)
  • Environment对象监控

Spring Cloud Commons

  • DiscoveryClient 接口
  • ServiceRegistry 接口
  • RestTemplate 使用 DiscoveryClient来获取目标主机host

Spring Cloud Context

启动级上下文

一个spring cloud应用依赖一个bootstrap上下文运作,它是整个应用中的父级容器。它会负责应用从外部加载应用的配置属性和读取本地的配置文件,并且这2部分配置属性共享一个Environment。默认情况下,启动级属性会被以最高优先级添加,所以它们不能被本地配置覆盖。

配置启动级上下文加载的属性需要使用bootstrap.yml而不是使用application.yml,一次能够将启动级属性和应用级属性的配置区分开,bootstrap.yml`简易配置案例:

spring:
  application:
    name: foo
  cloud:
    config:
      uri: ${SPRING_CONFIG_URI:http://localhost:8888}

如果需要配置应用的名称,则可以在bootstrap.ymlapplication.yml中配置spring.application.name属性,如果需要配置为applicationContext的ID,则只能在bootstrap.yml中配置。

同时我们也能够完全禁止处理启动级上下文处理通过设置spring.cloud.bootstrap.enabled=false属性

Application Context 继承关系

如果通过 SpringApplicationSpringApplicationBuilder进行构建应用,bootstrap上下文会自动的添加到应用中成为整个应用的父级上下文。并且Spring的子上下文会继承父级上下文的属性和profile,所以,应用能够包含许多额外的属性源:

  • “bootstrap”: 启动级上下文中发现有任何的 PropertySourceLocators ,则将会使用最高优先级的 CompositePropertySource。比如: Spring Cloud Config Server
  • “applicationConfig: [classpath:bootstrap.yml]”:如果配置了 bootstrap.yml (或者 .properties), 这个配置将用来配置启动级上下文。

设置ApplicationContext的父级上下文可以使用SpringApplicationBuilderparent(), child()sibling()方法,通常来说启动级上下文就是父级上下文,并且子上下文的属性会覆盖父上下文的同名属性

修改Bootstrap Properties的加载位置

bootstrap.yml (或 .properties) 所在位置可以JVM系统属性配置 spring.cloud.bootstrap.name (默认: bootstrap),spring.cloud.bootstrap.location (默认: 空) 或 spring.cloud.bootstrap.additional-location (默认: 空)

spring.cloud.bootstrap.location修改默认的位置。 spring.cloud.bootstrap.additional-location 将会添加额外的配置文件地址。实际上,这些配置都是用来创建启动级ApplicationContext,如果有profile属性(spring.profiles.active)被设置,存在于这个profile下的属性都会被加载,比如:bootstrap-development.properties 指定了 development 的profile。

覆盖”远程”配置的属性

通过启动级上下文加载的属性源都属于”远程”配置的属性,比如:Spring Cloud Config Server,默认不能被本地的配置覆盖,通过设置spring.cloud.config.allowOverride=true,一旦配置此属性就可以通过以下2个属性进行细化配置:

  • spring.cloud.config.overrideNone=true:只允许任何本地的配置文件覆盖
  • spring.cloud.config.overrideSystemProperties=false: 只允许系统属性、命令行参数和环境变量进行覆盖。

自定义启动级配置

/META-INF/spring.factories文件的org.springframework.cloud.bootstrap.BootstrapConfiguration属性可以添加我们自定义的启动级配置类。这个文件通过逗号分隔维护了一个@Configuration指定的用于创建上下文的配置类列表。

自定义启动级属性源

通过PropertySourceLocator接口可以实现定义属性源,比如,需要加载来自数据库或者不同的服务器的属性配置:

@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {

    @Override
    public PropertySource<?> locate(Environment environment) {
        return new MapPropertySource("customProperty",
                Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
    }

}

通过META-INF/spring.factories文件进行注册:

org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator

Environment修改事件监听

Spring容器会监听EnvironmentChangeEvent事件来对属性的改变做出响应,每当EnvironmentChangeEvent被监听到,会进行如下操作:

  • 重新绑定 @ConfigurationProperties 标注的bean
  • application.yaml文件中所有的 logging.level.*属性设置日志级别

RefreshScope

当一个bean的定义被@RefreshScope标注时,意味着这个bean在运行的生命周期可以被动态更新,这种作用域解决了bean只能在初始化时期注入属性,而不能在后期运行时动态更新的问题。比如,通过Environment修改DataSource的数据库地址。

除了@RefreshScope注解,还可以通过spring.cloud.refresh.extra-refreshable属性进行指定需要刷新的类

Spring默认使用的HikariDataSource不能使用RefreshScope,但是可以使用其他的DataSource实现

Spring容器中有一个RefreshScope的bean,它有一个refreshAll()方法来清空所有的bean缓存并刷新bean。同时也能够通过refresh(String)刷新指定的bean。

/refresh端点必须暴露:

management:
  endpoints:
    web:
      exposure:
        include: refresh

@RefreshScope也能使用在@Configuration标注的类上,但是可能会导致意想不到的结果,比如:@Configuration配置类中并不是所有的@Bean都是@RefreshScope的,在进行bean刷新的时候,任何依赖了这些bean的组件都将不能使用。在刷新时期,这些bean会被重新重新创建并被注入依赖。

加密与解密

Spring cloud提供了一个Environment的预置处理器(pre-processor),用来解密属性值,我们可以通过encrypt.*进行配置,但是必须依赖org.springframework.security:spring-security-rsa

endpoints

  • POST 请求访问 /actuator/env 更新 Environment 并且重新绑定 @ConfigurationProperties 属性类和日志级别
  • /actuator/refresh 重新加载上下文和刷新 @RefreshScope标注的 beans
  • /actuator/restart 重新启动 ApplicationContext (默认此端点关闭)
  • /actuator/pause/actuator/resume 调用 Lifecycle 的方法 ( ApplicationContextstop() and start() ).

如果禁用/actuator/restart端点, /actuator/pause/actuator/resume也将不能调用,因为这2个端点仅是/actuator/restart的特殊用列


文章作者: Ubi-potato
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ubi-potato !
评论
  目录