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.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
的方法 (ApplicationContext
的stop()
andstart()
).
如果禁用
/actuator/restart
端点,/actuator/pause
和/actuator/resume
也将不能调用,因为这2个端点仅是/actuator/restart
的特殊用列