Spring Cloud Config
application.yml 和 bootstrap.yml 区别
加载顺序
- bootstrap.yml 先加载
- application.yml 后加载
bootstrap.yml 用于应用程序上下文的引导阶段。
bootstrap.yml 由父 Spring ApplicationContext 加载。
父ApplicationContext被加载到使用application.yml 的之前
配置区别
bootstrap.yml 和 application.yml 都可以用来配置参数
- bootstrap.yml 可以理解为系统级别的一些参数配置,这些参数一般是不会变动的。
- application.yml 可以用来定义应用节级别的,如果搭配 spring-cloud-config 使用application.yml 里面定义的文件可以实现动态替换。
使用Stpring Cloud Config Server时,应在bootstrap.yml 中指定: - spring.application.name
- spring.cloud.config.server.git.url
- 一些加密/解密信息
application 的加载原理
启动上下文
Spring Cloud 会创建一个Bootstrap Context
,作为Spring应用的Application Context
的父上下文。初始化的时候,Bootstrap Context
复制从外部源加载配置属性并解析配置。 这两个上下文共享一个从外部获取的Environment
.Bootstrap
属性有高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap context
和 Application Context
有着不同的约定,所有新增了一个bootstrap.yml
文件,而不是使用application.yml
。保证Bootstarp Context
和 Application Context
配置的分离。
应用上下文层次结构
如果你通过 SpringApplicaion
或者 SpringApplicationBuilder
创建一个Application Context
,那么会为spring应用的Application Context
创建父上下文Bootstrap Context
。在Spring里有个特性,子上下文会继承父类的property sources
,会新增额外的property sources
。额外的property sources
有:
- “bootstrap”: 如果在Boostrap Context 扫描到PropertySourceLocator并且有属性,则会添加到CompositePropertySource.Spring Cloud COnfig 就是通过这种方式来添加属性,详情请查看源码 ConfigServicePropertySourceLocator。
- “applicationConfig:[classpath:bootstrap.yml]” (如果有 spring.profiles.active=production,则例如 applicationConfig:[classpath:/bootstrap.yml]#product): 如果你是用bootstrap.yml 来配置Bootstrap Context,他比application.yml 优先级别要低,它将添加到子上下文,作为Spring Boot 应用程序的一部分。
由于优先级规则,Bootstrap Context 不包含从Bootstrap.yml 来的数据,但可以用它作为默认设置。
你可以很容易的扩展任何你建立的上下文层次,可以使用它提供的接口,或者使用 SpringApplicationBuillder包含的方法(parent(),child(),sibling())。 Bootstrap Context 将是最高级别的父类。扩展的每一个Context都有自己的 bootstrap property source(有可能是空的)。扩展的每一个Context 都有不同 spring.application.name。 同一层层次的父子上下文原则上也有着不同的名称,因此,也会有不同的Config Server配置。子上下文的属性在相同名字的情况下将覆盖父上下文的属性。
注意:SpringApplicationBuilder允许共享Environment到所有层次,但是不是默认的。 因此,同级的兄弟上下文不在和父类共享一些东西的时候不一定有相同的profiles或者property sources。
修改Bootstrap属性配置
源码位置: BootstrapApplicationLister
1 | String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}"); |
bootstrap.yml 是有spring.cloud.bootstrap.name(默认:“bootstrap”) 或者 spring.cloud.bootstrap.location(默认空)。这些属性行为与spring.config.* 类似,通过它的Environment来配置引导ApplicationContext。如果有一个激活的profile(来源与 spring.profiles.active 或者 Environment 的Api构建),例如 bootstrap-development.properies 就是配置了 profile为development的配置文件。
覆盖远程属性
property sources 被bootstrap context添加到应用通常远程的方式,比如“Config Server”。默认情况下,本地的配置文件不能覆盖远程配置,但是可以通过启动命令参数来覆盖远程配置。如果需要本地文件覆盖远程文件,需要在远程配置文件里设置 spring.cloud.config.allowOverride=true
(这个配置不能在本地被设置)。一旦设置了这个权限,你可以配置更加细粒度的配置来配置覆盖的方式。
1 | spring.cloud.config.overrideNoe = true #覆盖任何本地属性 |
源文件详见 PropertySourceBootstrapProperties
自定义启动配置
bootstrap context 是依赖 /META-INF/spring.factories 文件里面的 org.springframework.cloud.bootstrap.BootstrapConfiguration 条目下面,通过逗号分隔的Spring @Configuration 类来建立的配置。任何main application context 需要自动注入的Bean可以在这里通过这种方式获取。这也是 ApplicationContextInitializer 建立@Bean的方式。可以通过 @Order来更改初始化序列,默认是”last”。
1 | # spring-cloud-context-1.1.1.RELEASE.jar |
你添加的自定义BootstrapConfiguration类没有错误的@ComponentScanned到你的主应用上下文,他们可能是不需要的。使用一个另外的包不被@ComponentScan或者@SpringBootApplication注解覆盖到。
bootstrap context 通过 spring.factories 的配置类初始化所有的Bean都会在SpringApplication启动前加入到它的上下文里去。
自定义引导配置来源: Bootstrap Property Sources
默认的property source
添加额外的配置是通过配置服务(Config Server),你也可以自定义添加 property soruce
通过实现 PropertySourceLocator
接口来添加。你可以使用它加配置属从不同的服务,数据库或者其他。
demo:
1 | @Configuration |
Environment 被 ApplicationContext建立,并传入 property sources(可能不同的profile有不同的属性),所以,你可以从Environment寻找找一些特别的属性。比如spring.application.name,它是默认的Config Server property source。
如果你建立了一个jar包,里面添加了一个 META-INF/spring.factories文件:org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator
。那么“CostomProperty” 的
参考资料
(SpringCloud入门之常用的配置文件 application.yml和 bootstrap.yml区别)[https://www.cnblogs.com/BlogNetSpace/p/8469033.html]
(Spring Boot)[https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/]
(Spring Boot)[https://github.com/spring-projects/spring-boot]