Spring Cloud 核心库简介
Spring Cloud Commons工程提供了两个库功能:Spring Cloud Context和Spring Cloud Commons。 Spring Cloud Context为Spring Cloud应用程序的ApplicationContext(bootstrap引导程序上下文,encryption加密,refreshScope刷新作用域和环境端点)提供实用程序和特殊服务。 Spring Cloud Commons是在不同的Spring Cloud实现中使用的一组抽象和通用类(例如,Spring Cloud Netflix与Spring 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.yml 或 application.yml中配置spring.application.name属性,如果需要配置为applicationContext的ID,则只能在bootstrap.yml中配置。
同时我们也能够完全禁止处理启动级上下文处理通过设置spring.cloud.bootstrap.enabled=false属性
Application Context 继承关系
如果通过 SpringApplication或 SpringApplicationBuilder进行构建应用,bootstrap上下文会自动的添加到应用中成为整个应用的父级上下文。并且Spring的子上下文会继承父级上下文的属性和profile,所以,应用能够包含许多额外的属性源:
- “bootstrap”: 启动级上下文中发现有任何的
PropertySourceLocators,则将会使用最高优先级的CompositePropertySource。比如:Spring Cloud Config Server。 - “applicationConfig:
[classpath:bootstrap.yml]”:如果配置了bootstrap.yml(或者.properties), 这个配置将用来配置启动级上下文。
设置ApplicationContext的父级上下文可以使用SpringApplicationBuilder的parent(), 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.CustomPropertySourceLocatorEnvironment修改事件监听
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的方法 (ApplicationContext的stop()andstart()).
如果禁用
/actuator/restart端点,/actuator/pause和/actuator/resume也将不能调用,因为这2个端点仅是/actuator/restart的特殊用列

