情景描述
最近在修復Eureka的靜態頁面加載不出的缺陷時,最終發現是遠程GIT倉庫將靜態資源訪問方式配置給禁用了(spring.resources.add-mappings=false)。雖然最后直接修改遠程GIT倉庫的此配置項給解決了(spring.resources.add-mappings=true),但是從中牽涉出的配置讀取優先級我們必須好好的再回顧下
springcloud config讀取倉庫配置
通過config client模塊來讀取遠程的倉庫配置,只需要在boostrap.properties文件中配置如下屬性即可
spring.application.name=eurekaspring.cloud.config.uri=http://localhost:8888spring.cloud.config.name=devspring.cloud.config.username=devspring.cloud.config.password=dev
其就會以GET方式去請求http://localhost:8888/eureka/dev地址從而將配置拉取下來。
當然上述的API地址也是需要被訪問服務器部署了config server服務方可調用,具體的細節就不展開了
外部源讀取優先級
我們都知道spring的配置屬性管理均是存放在Enviroment對象中,就以普通項目StandardEnvironment為例,其配置的存放順序可羅列如下
順位 | key | 來源 | 說明 |
---|---|---|---|
1 | commandLineArgs | 傳入main函數的參數列表 | Program arguments |
2 | systemProperties | System.getProperties() | JDK屬性列表、操作系統屬性、-D開頭的VM屬性等 |
3 | systemEnvironment | System.getEnv() | 環境屬性,例如JAVA_HOME/M2_HOME |
4 | ${file_name} | 配置文件 | 例如application.yml |
5 | defaultProperties | SpringApplicationBuilder#properties() |
那么遠程讀取的配置的存放應該放在上述的哪個位置呢?
我們都知道boostrap上下文通過暴露org.springframework.cloud.bootstrap.config.PropertySourceLocator接口來方便集成第三方的外部源配置讀取,比如本文提及的config client模塊中的org.springframework.cloud.config.client.ConfigServicePropertySourceLocator實現類。
但最終將外部源配置讀取以及插入至Environment對象中則是通過org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration類來完成的。
PropertySourceBootstrapConfiguration
此類也是ApplicationContextInitializer接口的實現類,閱讀過cloud源碼的都知道,此類被調用是在子類上下文初始化的時候,我們主要看下其復寫的initialize()方法
@Override public void initialize(ConfigurableApplicationContext applicationContext) { CompositePropertySource composite = new CompositePropertySource( BOOTSTRAP_PROPERTY_SOURCE_NAME); // 對在boostrap上下文類型為PropertySourceLocator的bean集合進行排序 AnnotationAwareOrderComparator.sort(this.propertySourceLocators); boolean empty = true; ConfigurableEnvironment environment = applicationContext.getEnvironment(); for (PropertySourceLocator locator : this.propertySourceLocators) { PropertySource<?> source = null; // 讀取外部配置源 source = locator.locate(environment); if (source == null) { continue; } logger.info("Located property source: " + source); composite.addPropertySource(source); empty = false; } if (!empty) { MutablePropertySources propertySources = environment.getPropertySources(); String logConfig = environment.resolvePlaceholders("${logging.config:}"); LogFile logFile = LogFile.get(environment); if (propertySources.contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) { propertySources.remove(BOOTSTRAP_PROPERTY_SOURCE_NAME); } // 插入至Environment環境對象中 insertPropertySources(propertySources, composite); reinitializeLoggingSystem(environment, logConfig, logFile); setLogLevels(applicationContext, environment); handleIncludedProfiles(environment); } }
新聞熱點
疑難解答