application.yml與bootstrap.yml的區別


一.簡述

Spring Boot 默認支持 properties(.properties) 和 YAML(.yml .yaml ) 兩種格式的配置文件,yml 和 properties 文件都屬於配置文件,功能一樣。

Spring Cloud 構建於 Spring Boot 之上,在 Spring Boot 中有兩種上下文,一種是 bootstrap,另外一種是 application,下面列舉這兩種配置文件的區別

1.加載順序
若application.yml 和bootstrap.yml 在同一目錄下:bootstrap.yml 先加載 application.yml后加載

bootstrap.yml 用於應用程序上下文的引導階段。bootstrap.yml 由父Spring ApplicationContext加載。

2.配置區別
bootstrap.yml 和 application.yml 都可以用來配置參數。

bootstrap.yml 用來程序引導時執行,應用於更加早期配置信息讀取。可以理解成系統級別的一些參數配置,這些參數一般是不會變動的。一旦bootStrap.yml 被加載,則內容不會被覆蓋。

application.yml 可以用來定義應用級別的, 應用程序特有配置信息,可以用來配置后續各個模塊中需使用的公共參數等。

3.屬性覆蓋問題
啟動上下文時,Spring Cloud 會創建一個 Bootstrap Context,作為 Spring 應用的 Application Context 的父上下文。

初始化的時候,Bootstrap Context 負責從外部源加載配置屬性並解析配置。這兩個上下文共享一個從外部獲取的 Environment。Bootstrap 屬性有高優先級,默認情況下,它們不會被本地配置覆蓋。

也就是說如果加載的 application.yml 的內容標簽與 bootstrap 的標簽一致,application 也不會覆蓋 bootstrap,而 application.yml 里面的內容可以動態替換。

二、典型的應用場景如下:

  • 當使用 Spring Cloud Config Server 的時候,你應該在 bootstrap.yml 里面指定 spring.application.name 和 spring.cloud.config.server.git.uri
  • 和一些加密/解密的信息

技術上,bootstrap.yml 是被一個父級的 Spring ApplicationContext 加載的。這個父級的 Spring ApplicationContext是先加載的,在加載application.yml 的 ApplicationContext之前。

為何需要把 config server 的信息放在 bootstrap.yml 里?

當使用 Spring Cloud 的時候,配置信息一般是從 config server 加載的,為了取得配置信息(比如密碼等),你需要一些提早的或引導配置。因此,把 config server 信息放在 bootstrap.yml,用來加載真正需要的配置信息。

三、高級使用場景

啟動上下文

Spring Cloud會創建一個Bootstrap Context,作為Spring應用的Application Context的父上下文初始化的時候,Bootstrap Context負責從外部源加載配置屬性並解析配置。這兩個上下文共享一個從外部獲取的EnvironmentBootstrap屬性有高優先級,默認情況下,它們不會被本地配置覆蓋。 Bootstrap contextApplication Context有着不同的約定,所以新增了一個bootstrap.yml文件,而不是使用application.yml (或者application.properties)。保證Bootstrap ContextApplication Context配置的分離。

下面是一個例子: bootstrap.yml

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

推薦在bootstrap.yml or application.yml里面配置spring.application.name. 你可以通過設置spring.cloud.bootstrap.enabled=false來禁用bootstrap

應用上下文層次結構

如果你通過SpringApplication或者SpringApplicationBuilder創建一個Application Context,那么會為spring應用的Application Context創建父上下文Bootstrap Context。在Spring里有個特性,子上下文會繼承父類的property sources and profiles ,所以main application context 相對於沒有使用Spring Cloud Config,會新增額外的property sources。額外的property sources有:

  • “bootstrap” : 如果在Bootstrap Context掃描到PropertySourceLocator並且有屬性,則會添加到CompositePropertySource。**Spirng Cloud Config就是通過這種方式來添加的屬性的**,詳細看源碼ConfigServicePropertySourceLocator`。下面也也有一個例子自定義的例子。
  • “applicationConfig: [classpath:bootstrap.yml]” ,(如果有spring.profiles.active=production則例如 applicationConfig: [classpath:/bootstrap.yml]#production): 如果你使用bootstrap.yml來配置Bootstrap Context,他比application.yml優先級要低。它將添加到子上下文,作為Spring Boot應用程序的一部分。下文有介紹。

由於優先級規則,Bootstrap Context不包含從bootstrap.yml來的數據,但是可以用它作為默認設置。

你可以很容易的擴展任何你建立的上下文層次,可以使用它提供的接口,或者使用SpringApplicationBuilder包含的方法(parent()child()sibling())。Bootstrap Context將是最高級別的父類。擴展的每一個Context都有有自己的bootstrap property source(有可能是空的)。擴展的每一個Context都有不同spring.application.name。同一層層次的父子上下文原則上也有一有不同的名稱,因此,也會有不同的Config Server配置。子上下文的屬性在相同名字的情況下將覆蓋父上下文的屬性。

注意SpringApplicationBuilder允許共享Environment到所有層次,但是不是默認的。因此,同級的兄弟上下文不在和父類共享一些東西的時候不一定有相同的profiles或者property sources

修改Bootstrap屬性配置

源碼位置BootstrapApplicationListener

String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");

String configLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.location:}");

Map<String, Object> bootstrapMap = new HashMap<>();bootstrapMap.put("spring.config.name",configName);
if(StringUtils.hasText(configLocation)){
    bootstrapMap.put("spring.config.location", configLocation);
} 

bootstrap.yml是由spring.cloud.bootstrap.name(默認:”bootstrap”)或者spring.cloud.bootstrap.location(默認空)。這些屬性行為與spring.config.*類似,通過它的Environment來配置引導ApplicationContext。如果有一個激活的profile(來源於spring.profiles.active或者Environment的Api構建),例如bootstrap-development.properties 就是配置了profiledevelopment的配置文件.

覆蓋遠程屬性

property sourcesbootstrap context 添加到應用通常通過遠程的方式,比如”Config Server”。默認情況下,本地的配置文件不能覆蓋遠程配置,但是可以通過啟動命令行參數來覆蓋遠程配置。**如果需要本地文件覆蓋遠程文件,需要在遠程配置文件里設置授權 **
spring.cloud.config.allowOverride=true(這個配置不能在本地被設置)。一旦設置了這個權限,你可以配置更加細粒度的配置來配置覆蓋的方式,

比如:

  • spring.cloud.config.overrideNone=true 覆蓋任何本地屬性
  • spring.cloud.config.overrideSystemProperties=false 僅僅系統屬性和環境變量
    源文件見PropertySourceBootstrapProperties

自定義啟動配置

bootstrap context是依賴/META-INF/spring.factories文件里面的org.springframework.cloud.bootstrap.BootstrapConfiguration條目下面,通過逗號分隔的Spring @Configuration類來建立的配置。任何main application context需要的自動注入的Bean可以在這里通過這種方式來獲取。這也是ApplicationContextInitializer建立@Bean的方式。可以通過@Order來更改初始化序列,默認是”last”。

# spring-cloud-context-1.1.1.RELEASE.jar
# spring.factories
# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.context.restart.RestartListener

# Bootstrap components
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.PropertyPlaceholderAutoConfiguration

警告

小心,你添加的自定義BootstrapConfiguration類沒有錯誤的@ComponentScanned到你的主應用上下文,他們可能是不需要的。
使用一個另外的包不被@ComponentScan或者@SpringBootApplication注解覆蓋到。

bootstrap context通過spring.factories配置的類初始化的所有的Bean都會在SpingApplicatin啟動前加入到它的上下文里去。

自定義引導配置來源:Bootstrap Property Sources

默認的property source添加額外的配置是通過配置服務(Config Server),你也可以自定義添加property source通過實現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"));
}

EnvironmentApplicationContext建立,並傳入property sources(可能不同個profile有不同的屬性),所以,你可以從Environment尋找找一些特別的屬性。比如spring.application.name,它是默認的Config Server property source

如果你建立了一個jar包,里面添加了一個META-INF/spring.factories文件:

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

那么,”customProperty“的PropertySource將會被包含到應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM