SpringBoot加載配置文件的完整步驟是什么-創(chuàng)新互聯(lián)

這篇文章給大家介紹SpringBoot加載配置文件的完整步驟是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)大廠免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了1000+企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

SpringBoot從哪里開始加載配置文件?

SpringBoot加載配置文件的入口是由ApplicationEnvironmentPreparedEvent事件進(jìn)入的,SpringBoot會在SpringApplication的構(gòu)造函數(shù)中通過spring.factories文件獲取ApplicationListener的實(shí)例類:

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { ... setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); ...}

spring.factories中有一個ConfigFileApplicationListener類,它會監(jiān)聽ApplicationEnvironmentPreparedEvent然后再加載配置文件 :

# Application Listenersorg.springframework.context.ApplicationListener= org.springframework.boot.context.config.ConfigFileApplicationListener...

有了事件和事件處理的類后,再找出發(fā)送事件的地方,就可以搞清楚SpringBoot是怎么加載配置文件的了,SpringBoot在啟動之前先初始化好SpringApplicationRunListeners這個類,它會實(shí)現(xiàn)SpringApplicationRunListener接口然后對事件進(jìn)行轉(zhuǎn)發(fā):

class SpringApplicationRunListeners { private final Log log; private final List<SpringApplicationRunListener> listeners; SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) { this.log = log; this.listeners = new ArrayList<>(listeners); }  void environmentPrepared(ConfigurableEnvironment environment) { for (SpringApplicationRunListener listener : this.listeners) { listener.environmentPrepared(environment); } } ...}

獲取SpringApplicationRunListeners的代碼如下:

private SpringApplicationRunListeners getRunListeners(String[] args) { Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class }; return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));}

同樣也會去加載spring.factories文件,該文件有一個EventPublishingRunListener類,該類的作用就是SpringBoot的事件轉(zhuǎn)換成ApplicationEvent發(fā)送出去。

# Run Listenersorg.springframework.boot.SpringApplicationRunListener=\org.springframework.boot.context.event.EventPublishingRunListener

小結(jié)

SpringBoot會將事件轉(zhuǎn)換成ApplicationEvent再分發(fā)  SpringBoot是通過監(jiān)聽ApplicationEnvironmentPreparedEvent事件來加載配置文件的  ConfigFileApplicationListener是處理配置文件的主要類

SpringBoot從哪些地方加載配置文件?

上面已經(jīng)分析到ConfigFileApplicationListener是處理配置文件的主要類,然后進(jìn)一步的查看SpringBoot是從哪些地址加載配置文件,進(jìn)入ConfigFileApplicationListener類后會有兩個默認(rèn)的常量:

private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";private static final String DEFAULT_NAMES = "application";

首先在沒有任何配置的情況下,會從DEFAULT_SEARCH_LOCATIONS常量列出來的位置中加載文件名為DEFAULT_NAMES(.properties或yml)的文件,默認(rèn)位置包括:

classpath根目錄(classpath:/)  classpath里面的config文件目錄(classpath:/config/)  程序運(yùn)行目錄(file:./)  程序運(yùn)行目錄下的config目錄(file:./config/)

上面說的是沒有額外配置的情況,SpringBoot足夠靈活可以指定配置文件搜索路徑、配置文件名,在ConfigFileApplicationListener類中有個getSearchLocations方法,它主要負(fù)責(zé)獲取配置搜索目錄:

private Set<String> getSearchLocations() {if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) { return getSearchLocations(CONFIG_LOCATION_PROPERTY); } Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY); locations.addAll( asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS)); return locations;}

它的操作步驟大致如下:

  1. 檢查是否有spring.config.location屬性,如果存在則直接使用它的值  從spring.config.additional-location屬性中獲取搜索路徑  將默認(rèn)搜索路徑添加到搜索集合

這里就可以確定SpringBoot配置的搜索路徑有兩種情況:如果配置了spring.config.location則直接使用,否則使用spring.config.additional-location的屬性值 + 默認(rèn)搜索路徑。

SpringBoot是如何支持yaml和properties類型的配置文件?

SpringBoot的配置支持properties和yaml文件,SpringBoot是如何解析這兩種文件的呢,繼續(xù)分析ConfigFileApplicationListener這個類,里面有個子類叫Loader加載配置文件主要的工作就是由這貨負(fù)責(zé),但是直接讀取properties和yaml并轉(zhuǎn)換成PropertySource還是由里面的PropertySourceLoader負(fù)責(zé):

Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) { ... this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());}

構(gòu)造Loader對象的時候就會先加載PropertySourceLoader,加載方式還是從spring.factories中讀?。?/p>

# PropertySource Loadersorg.springframework.boot.env.PropertySourceLoader=\org.springframework.boot.env.PropertiesPropertySourceLoader,\org.springframework.boot.env.YamlPropertySourceLoader

其中配置了兩個PropertySourceLoader的實(shí)現(xiàn)類:

PropertiesPropertySourceLoader  YamlPropertySourceLoader

看名字就知道是分別負(fù)責(zé)properties和yaml的啦。

如果要支持json配置應(yīng)該如何做?

如果不喜歡properties和yaml這兩種格式,想要定義json做為配置文字格式可以直接定義json類型的PropertySourceLoader:

public class JSONPropertySourceLoader implements PropertySourceLoader { @Override public String[] getFileExtensions() { return new String[] {"json"}; }  @Override public List<PropertySource<?>> load(String name, Resource resource) throws IOException { if(resource == null || !resource.exists()){  return Collections.emptyList(); } Map<String, Object> configs = JSON.parseObject(resource.getInputStream(), Map.class); return Collections.singletonList(  new MapPropertySource(name, configs) ); }}

然后在resources目錄里面建立個META-INF,再添加個spring.factories里面的內(nèi)容如下:

org.springframework.boot.env.PropertySourceLoader=\com.csbaic.arch.spring.env.loader.JSONPropertySourceLoader

最后在resources目錄里面建個application.json的配置文件 :

{ "spring.application.name": "JSONConfig"}

正常啟動SpringBoot獲取spring.applicaiton.name的配置的值就是JSONConfig:

2019-11-02 14:50:17.730 INFO 55275 --- [ main] c.c.a.spring.env.SpringEnvApplication : JSONConfig

SpringBoot的配置優(yōu)先級是怎么樣的?

SpringBoot中有個PropertySource接口,專門用來保存屬性常見的實(shí)現(xiàn)類有:

CommandLinePropertySource  MapPropertySource  SystemEnvironmentPropertySource  ....

另外為了集中管理PropertySource還抽象出一個PropertySources接口,PropertySources就一個實(shí)現(xiàn)類叫:MutablePropertySources,它將所有的PropertySource都放置在一個名叫propertySourceList集合中,同時提供一些修改操作方法:

public void addFirst(PropertySource<?> propertySource) {}public void addLast(PropertySource<?> propertySource) {}public void addBefore(String relativePropertySourceName, PropertySource<?> propertySource) {}public void addAfter(String relativePropertySourceName, PropertySource<?> propertySource) {}public int precedenceOf(PropertySource<?> propertySource) { }public PropertySource<?> remove(String name) {}public void replace(String name, PropertySource<?> propertySource) {}

所有的PropertySource都保存在propertySourceList中,越小的索引優(yōu)先級越高,所以如果想要覆蓋屬性只要保證優(yōu)化級夠高就行。

placeholder是如何被解析的?

繼續(xù)分析ConfigFileApplicationListener的Loader子類,在構(gòu)造時還會創(chuàng)建一個PropertySourcesPlaceholdersResolver,placeholder的解析都由它來完成:

Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) { this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);}

分析PropertySourcesPlaceholdersResolver發(fā)現(xiàn),真正完成解析是由PropertyPlaceholderHelper完成,PropertySourcesPlaceholdersResolver 在構(gòu)造的時候就會創(chuàng)建一個PropertyPlaceholderHelper

public PropertySourcesPlaceholdersResolver(Iterable<PropertySource<?>> sources, PropertyPlaceholderHelper helper) { this.sources = sources; this.helper = (helper != null) ? helper : new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,  SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true);}

PropertySourcesPlaceholdersResolver 在創(chuàng)建 PropertyPlaceholderHelper 的時候會傳遞三個參數(shù):前綴、后綴、默認(rèn)值分割符,分別由以下三個常量表示:

public static final String PLACEHOLDER_PREFIX = "${";public static final String PLACEHOLDER_SUFFIX = "}";public static final String VALUE_SEPARATOR = ":";

這樣 PropertyPlaceholderHelper 在解析placeholder時就能知道以什么格式來解析比如:${spring.application.name}這個placeholder就會被解析成屬性值。

總結(jié)

SpringBoot的配置非常靈活配置可以來自文件、環(huán)境變量、JVM系統(tǒng)屬性、配置中心等等,SpringBoot通過PropertySource和PropertySources實(shí)現(xiàn)屬性優(yōu)先級、CRUD的統(tǒng)一管理,為開發(fā)者提供統(tǒng)一的配置抽象。

關(guān)于SpringBoot加載配置文件的完整步驟是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

網(wǎng)頁題目:SpringBoot加載配置文件的完整步驟是什么-創(chuàng)新互聯(lián)
瀏覽路徑:http://bm7419.com/article28/dgoocp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站內(nèi)鏈、網(wǎng)站設(shè)計公司、自適應(yīng)網(wǎng)站、App設(shè)計網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站