我在自己写点东西玩的时候需要读配置文件,又不想引包,于是打算扣点spring boot读取配置文件的代码出来,当然只是读配置文件没必要这么麻烦,不过反正闲着也是闲着,扣着玩了。
具体启动过程以前的博客写过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; } |
关于监听器的过程在开头说的那篇的一系列中也说的挺细的,这里不介绍了:
都是监听器相关的部分,略了,springapplicationrunlisteners类中:
1
2
3
4
5
|
public void environmentprepared(configurableenvironment environment) { for (springapplicationrunlistener listener : this .listeners) { listener.environmentprepared(environment); } } |
eventpublishingrunlistener:
onapplicationenvironmentpreparedevent事件触发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监听器执行:
现在这个postprocessors中包含json之类其他的监听器,不过我现在只想扣出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基本是没用的,这东西现在已经很少用到了,这个环境当然是没配的:
主要是下面这部分:
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为名字的指定类型的配置文件:
我只关心application.properties,它是上面循环中的一次,走进了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); } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/saaav/p/6937602.html?utm_source=tuicool&utm_medium=referral