springboot 부하 프로파일 절차있는 application.properties

최근에 나는 소스 코드는 취사 방법이 될 것이다 읽을 질문, 발견했다. 신속 핵심 문제 및 로직의 일부를 파악할 수 있도록, 그들은 구체적인 세부 사항 만 시간 낭비로 얻을 수 없겠죠. 당신은 문제를 해결하는 것은 내부 층에 외부에서 점차 또한 당신이 완료되면, 그래서 시간의 특정 지점의 일부를 알고 다음 읽기를 판명 할 경우, 구체적으로는 거친에서 그것을 이해합니다.

그런 다음 공식 컨텐츠 종이를 입력

프로필 (단순 여기, application.yml도) 개발을 위해 springboot를 사용할 때 우리는 종종 연락처 application.properties에 와서, 우리는 몇 가지 중요한 문제에 초점을 맞출 수 있습니다

질문하기

1) 다음 springboot 시작, 때로드있는 application.properties?

2) 기본로드 프로세스는 방법의 종류입니까?

3) 지정된 시간에 여러 환경 프로파일을 구성하는 방법로드입니까?

질문 1 : 파일이로드 될 때있는 application.properties?

우선, 우리는 구성 파일을로드 이벤트 리스너 application.properties 방법을 사용하여 springboot를 알아야합니다. 즉, 프로그램이 완료 나중에 일이 해당 이벤트 리스너를 트리거 게시 할의 EventListener를 설정의 시작 부분에서 시작됩니다.

springboot 환경 개체를 만든 후에는 리스너 EventPublishingRunListener을 트리거 갈 것이다하는 ApplicationEnvironmentPreparedEvent을 게시되며,이 이벤트는 ConfigFileApplicationListener을 트리거합니다. ConfigFileApplicationListener application.properties 코어 클래스를로드,이 청취자 클래스입니다.

의 코드와 실행 방법부터 시작하자

getRunListeners (인수) 방법은 spring.factories 인터페이스 구현 클래스에서 SpringApplicationRunListener을 얻을 것이다, 같은

这个时候EventPublishingRunListener这个监听器将会被加载,然后调用prepareEnvironment的时候顺带着被做实参传入,我们进入prepareEnvironment方法。

我们看到,prepareEnvironment方法会创建一个Environment实例对象并进行一些配置处理,而后就会触发EventPublishingRunListener监听器,执行其environmentPrepared方法。这里我们可以猜测到EventPublishingRunListener调度角色,会构造出对应的事件并分发给对应的监听器。

进入EventPublishingRunListener,我们看到该方法创建了一个ApplicationEnvironmentPreparedEvent事件,然后广播了出去。

 

那么这个新建的事件广播给哪些监听器呢?getApplicationListeners方法将会给出答案,我们断点就可以看到

我们看到了一开始说的ConfigFileApplicationListener监听器出现了,invokeListener方法将会触发该监听器的onApplicationEvent方法。我们再跟进ConfigFileApplicationListener的onApplicationEvent方法

继续跟进onApplicationEnvironmentPreparedEvent方法

我们看到loadPostProcessors方法去加载了Environment的后置处理器,并且调用postProcessEnvironment方法。ConfigFileApplicationListener也实现了EnvironmentPostProcessor接口,所以postProcessEnvironment方法再当前类中有实现。我们跟进当前类的postProcessEnvironment方法。

再跟进addPropertySources方法

addPropertySources方法将会实例化一个加载器Loader并开始加载配置。

到这里我们基本上知道第一个问题的答案,Springboot是在Environment创建以后发布一个事件触发ConfigFileApplicationListener监听器并开始加载application.properties配置的。

问题2:默认加载过程是怎么样的?

 上面,我们知道addPropertySources方法最终是实例化一个Loader并调用其load方法去加载配置文件,显然application.properties这个配置文件的加载过程也就再这里实现。

我们先看看Loader的构造方法做了什么

这个构造方法值得关注的一点是它从spring.factories中加载了PropertySourceLoader接口的实现类,该接口顾名思义就是用来加载配置文件资源的,接口的实现类如下

 

前者加载properties、xml扩展文件,后者加载yml、yaml扩展文件

回到addPropertySources方法

在Loader实例化完毕以后,就调用其load()方法,我们跟进load方法看看

很显然,load方法实现了加载文件的核心逻辑。我们先关注一下initiallizeProfiles()方法

我们注意到,一开始添加了一个null,这个是为了保证默认的application.properties会被优先处理。

而initializeProfiles方法希望从Environment里面拿到现有的profiles配置,不过显然默认是不会有的,所以size==1,将会拿到Environment中默认的profiles,而默认的profiles只会有一个default。

所以initializeProfiles方法最终将产生一个这样的数据

profiles = [null, "default"]

回到load方法,继续往下看

首先profile=null会被找到,由于为null,所以将会直接调用另一个load方法,我们跟进另一个load方法

这里我们看到getSearchLocations将会获取所有待搜索的目录位置,我们进入getSearchLocations方法

可以看到,Environment默认是没有配置的,所以最终会找到默认的常量值,如下:

到这里,我们通过getSearchLocations方法获取了默认会被搜索的文件夹路径,回到刚才的load方法

 

找到待搜索目录以后,将会遍历该目录,再通过getSearchNames()方法获取待搜索文件的名字,我们看看getSearchNames()方法

显然和getSearchLocations方法一样,最后会取到默认值,如

我们看到,被搜索的配置文件名默认是"application"。

到这里,我们拿到了待搜索的目录、待搜索的文件名,下面就是去目录下搜索对应的文件了,回到刚刚的load方法

跟进另一个load方法

我们已经获得了name=application,所以直接进入下面一段代码。

首先遍历了propertySourceLoaders,这个ProperySourceLoader也就是我们一开始Loader实例化的时候从spring.factories文件加载出来的两个加载器properties、yml文件加载器。

在遍历中,将会根据:目录 + 文件名 + 文件扩展名 去加载默认的配置文件,例如:classpath:/application.properties,我们跟进loadForFileExtension方法

我们一开始的profile=null,所以这里将直接调用另一个load方法,跟进看看,这个load方法代码较长,截取核心如下

首先loadDocuments方法将会使用load加载器加载配置文件为Document,然后document会被遍历分别处理。这里的consumer是从一开始的load方法传入的,我们回头看看第一个load,如

我们看到consumer是addToLoaded方法返回出来的,并且将MutablePropertySourcs的addLast作为方法应用传递进去,我们进入addToLoaded方法

我们看到,之前Loader加载出来的每个document的PropertySource将会被添加到loaded对象当中,这里我们稍微关注一下loaded对象是什么结构,如

loaded对象承担的责任是存储Profile和Properties的属性值的映射,所以我们第一个application.properties文件加载到loaded以后就变成 key=null,value=Application配置文件的属性值了。

这样,我们一个application.properties文件也就被加载出来了,还需要最后一步将它添加到Environment环境变量当中,我们回到最开始的load方法,如

addLoadedPropertySources方法将会把每个consumer添加到loaded对象当中的PropertySource给添加到Environment中,我们跟进addLoadedPropertySources方法

这里做了一个遍历,我们跟进addLoadedPropertySource方法

source被添加到了destination中,也就是Environment的成员对象MutablePropertySources当中。

到这里,第二个问题的解答就结束了,默认的加载过程也就是将application.properties或者application.yml通过加载器加载为PropertySource,并添加到Environment当中。

问题3:配置多环境指定profile的时候又是什么原理?

配置多环境切换的时候我们通常是这样做的

application.properties文件中指定那个启用,这里配置启用dev文件

那么,为什么application.properties指定了spring.profiles.active以后就会自动加载对应的配置文件呢?比如这里指定了dev,那么就会去加载application-dev.properties配置文件。

首先,我们是在application.properties文件中指定的,所以加载什么配置文件也肯定是在application.properties文件加载完以后决定的,我们进入刚才讨论第二个问题的时候loadDocuments的位置,如图

我们看到application.properties配置的profile会被拿出来,再进入addActiveProfiles看看添加到哪里去

直接被添加到了原先profiles=[null, "default"]的集合当中,并且最后还把"default"给移除掉了。这说明当加载完application.properties以后,相应的profiles将被重新指定,我们回到一开始的load方法中

load方法将找到配置的"dev",并且跟之前一样调用load方法。我们再一路跟进,直到loadForFileExtension方法

我们看到,当有profile存在的时候,文件名 = 前缀 + profile + 扩展名,例如 application-dev.properties,并加载该文件,获取PropertySource添加到loaded中,并最终加载到Environment当中。到这里,第三个问题就解答完毕了。

springboot加载配置文件还有很多小细节值得了解,比如中文乱码问题、加载顺序问题、重复配置覆盖问题等等~

 

추천

출처www.cnblogs.com/lay2017/p/11456556.html