我在自己寫點東西玩的時候需要讀配置文件,又不想引包,于是打算扣點spring boot讀取配置文件的代碼出來,當(dāng)然只是讀配置文件沒必要這么麻煩,不過反正閑著也是閑著,扣著玩了。
具體啟動過程以前的博客寫過spring boot啟動過程(一),這次入口在springapplication類中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private configurableenvironment prepareenvironment( springapplicationrunlisteners listeners, applicationarguments applicationarguments) { // create and configure the environment configurableenvironment environment = getorcreateenvironment(); configureenvironment(environment, applicationarguments.getsourceargs()); //此處讀取 listeners.environmentprepared(environment); if (iswebenvironment(environment) && this .webapplicationtype == webapplicationtype.none) { environment = converttostandardenvironment(environment); } return environment; } |
關(guān)于監(jiān)聽器的過程在開頭說的那篇的一系列中也說的挺細的,這里不介紹了:
都是監(jiān)聽器相關(guān)的部分,略了,springapplicationrunlisteners類中:
1
2
3
4
5
|
public void environmentprepared(configurableenvironment environment) { for (springapplicationrunlistener listener : this .listeners) { listener.environmentprepared(environment); } } |
eventpublishingrunlistener:
onapplicationenvironmentpreparedevent事件觸發(fā)org\springframework\boot\spring-boot\2.0.0.build-snapshot\spring-boot-2.0.0.build-20170421.122111-547-sources.jar!\org\springframework\boot\context\config\configfileapplicationlistener.java監(jiān)聽器執(zhí)行:
現(xiàn)在這個postprocessors中包含json之類其他的監(jiān)聽器,不過我現(xiàn)在只想扣出properties的代碼,別的先略過,反正其實也沒什么,本來也是想看看它的思路,扣著玩,不要太在意。
1
2
3
4
5
|
protected void addpropertysources(configurableenvironment environment, resourceloader resourceloader) { randomvaluepropertysource.addtoenvironment(environment); new loader(environment, resourceloader).load(); } |
1
2
3
4
5
|
loader(configurableenvironment environment, resourceloader resourceloader) { this .environment = environment; this .resourceloader = resourceloader == null ? new defaultresourceloader() : resourceloader; } |
1
2
|
this .classloader = classutils.getdefaultclassloader(); //其實也就是thread.currentthread().getcontextclassloader(); |
下面就是真正加載了配置文件的load方法了,先是初始化propertysourcesloader和一些臨時的集合:
1
2
3
4
5
6
7
8
9
10
|
this .propertiesloader = new propertysourcesloader(); this .activatedprofiles = false ; this .profiles = collections.aslifoqueue( new linkedlist<profile>()); this .processedprofiles = new linkedlist<>(); // pre-existing active profiles set via environment.setactiveprofiles() // are additional profiles and config files are allowed to add more if // they want to, so don't call addactiveprofiles() here. set<profile> initialactiveprofiles = initializeactiveprofiles(); this .profiles.addall(getunprocessedactiveprofiles(initialactiveprofiles)); |
這些集合其實如果沒配置profile基本是沒用的,這東西現(xiàn)在已經(jīng)很少用到了,這個環(huán)境當(dāng)然是沒配的:
主要是下面這部分:
1
2
3
4
5
6
7
8
9
10
11
12
|
for (string location : getsearchlocations()) { if (!location.endswith( "/" )) { // location is a filename already, so don't search for more // filenames load(location, null , profile); } else { for (string name : getsearchnames()) { load(location, name, profile); } } } |
就是去指定目錄下去找各種以application為名字的指定類型的配置文件:
我只關(guān)心application.properties,它是上面循環(huán)中的一次,走進了doloadintogroup方法的下面那句:
1
2
3
4
5
6
7
|
private map<string, ?> loadproperties(resource resource) throws ioexception { string filename = resource.getfilename(); if (filename != null && filename.endswith(xml_file_extension)) { return (map) propertiesloaderutils.loadproperties(resource); } return new origintrackedpropertiesloader(resource).load(); } |
這個resource其實只是封裝了一下inputstream,具體的讀取。。。反正也沒啥特別的讀法:
讀出的key和value放在map<string, origintrackedvalue>:
1
2
3
4
5
6
|
private void put(map<string, origintrackedvalue> result, string key, origintrackedvalue value) { if (!key.isempty()) { result.put(key, value); } } |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/saaav/p/6937602.html?utm_source=tuicool&utm_medium=referral