美文网首页
springboot批量加载自定义配置文件

springboot批量加载自定义配置文件

作者: 一鸣一菲 | 来源:发表于2018-08-30 16:13 被阅读0次

    一,加载自定义配置文件

    springboot启动时会默认加载application.properties和application.yml以及application-{profile}.properties和application-{profile}.yml

    profile为对应的环境变量,比如dev,所以一般的资源文件结构如下:

    如果配置内容太多的话,就会显得很不方便,解决方案一般会分成多个不同的配置文件,期望加载application.yml后,会加载对应profile文件夹下的所有配置文件。

    分多个配置文件的接口如下:

    所以下面开始工作吧(大概思路是,利用EnvironmentPostProcessor接口,读取自定义文件夹,把内容加载到environment里去)

    1,新建实现实现EnvironmentPostProcessor的类O2oClientEnvironmentPostProcessor

    2,利用PathMatchingResourcePatternResolver加载多个文件

    3,PropertySourceLoader读取相应的配置文件,这里的location可以自己定义,本文为classpath:{profile}/client-*.fileExtension,如果profile为dev,PropertySourceLoader为YamlPropertySourceLoader的话,则为classpath:dev/client-*.yml,就会加载dev文件夹下以client-开头的所有yml文件。

    4,添加进environment。

    内容如下:

    类写好了,下面让它起作用,在META-INF/spring.factories下面配置

    org.springframework.boot.env.EnvironmentPostProcessor=com.mama100.o2o.client.config.O2oClientEnvironmentPostProcessor

    然后就OK了,可以直接注入自定义文件的属性。

    二,官网的说明

    官网文档关于EnvironmentPostProcessor的说明,举例是加载单个文件的,点击进入spring官方文档。懒得点的话,我把内容也复制进这里了。

    三,原理

    下面我们看看springboot启动的时候,在哪执行我们的代码的。(本来以为有专门代码格式的,结果没有,文字版没法看,那就截图吧)

    1,入口函数不多说

    2,大概就会new一个SpringApplication的实例来run。

    3,new实例时会查找所有jar包里面META-INF/spring.factories配置的org.springframework.context.ApplicationListener,并设到实例的属性listeners中。

    4,再来看看run,这里就是主流程了,这方法有个局部变量listeners,不要和SpringApplication的属性listeners搞混。关注浅蓝色阴影背景部分。

    4.1,先看看这个局部Listeners的来源,也是从META-INF/spring.factories下面查找,发现有
    # Run Listeners
    org.springframework.boot.SpringApplicationRunListener=\
    org.springframework.boot.context.event.EventPublishingRunListener

    然后会把EventPublishingRunListener实例化,可以看到,getSpringFactoriesInstances方法里的入参args里面添加了this,就是把SpringApplication传递给EventPublishingRunListener,这样实例化的时候可以获取SpringApplication的属性listeners,最后封装成SpringApplicationRunListeners返回,属性listeners只有EventPublishingRunListener的实例。

    4.2,EventPublishingRunListener实例化的时候,把之前SpringApplication的属性listeners逐一添加到initialMulticaster,当然也包括org.springframework.boot.context.config.ConfigFileApplicationListener

    5,回到第4步的再来看看run,继续往下走

    5.1现在看看准备环境,传递了局部的listeners,最终是调用了EventPublishingRunListener的environmentPrepared方法(参考4.1,循环里的属性listeners只有EventPublishingRunListener的实例)。

    5.2EventPublishingRunListener通过initialMulticaster发布事件ApplicationEnvironmentPreparedEvent

    5.3initialMulticaster发布事件,getApplicationListeners就能获取到之前SpringApplication的属性listeners(参考4.2EventPublishingRunListener实例化的时候,把之前SpringApplication的属性listeners逐一添加到initialMulticaster,当然也包括org.springframework.boot.context.config.ConfigFileApplicationListener)

    5.4,最终会调用listener.onApplicationEvent(event),其中也就是会调用ConfigFileApplicationListener中的onApplicationEvent方法,当然,这里还会调用到其它Listener中的onApplicationEvent方法。

    5.5,再来看看ConfigFileApplicationListener中的监听代码,事件类型是ApplicationEnvironmentPreparedEvent(参考5.2EventPublishingRunListener通过initialMulticaster发布事件ApplicationEnvironmentPreparedEvent)

    看loadPostProcessors(),这里会查找META-INF/spring.factories下org.springframework.boot.env.EnvironmentPostProcessor的类,其中就包括了我们的类O2oClientEnvironmentPostProcessor

    然后就会调用我们的O2oClientEnvironmentPostProcessor的postProcessEnvironment方法了,

    ConfigFileApplicationListener也是EnvironmentPostProcessor类,这里有加载默认配置文件的代码,O2oClientEnvironmentPostProcessor也是参考这个类写出来的,具体信息请读者自己研究。

    到这里,我们的代码就已经成功执行了。后面的就不分析了。总结一下,springboot启动的时候会初始化一系列listeners,并发布不同阶段的事件,其中ConfigFileApplicationListener会监听ApplicationEnvironmentPreparedEvent,在处理这个事件中,会查找META-INF/spring.factories下org.springframework.boot.env.EnvironmentPostProcessor的所有类,并执行其中的postProcessEnvironment方法。

    相关文章

      网友评论

          本文标题:springboot批量加载自定义配置文件

          本文链接:https://www.haomeiwen.com/subject/ipdrwftx.html