spring-cloud-kubernete-config会自动读取引用的ConfigMap资源中的配置信息,并写入到Environment中。
虽然通过配置中心加载配置可以去掉配置文件,但本地测试我们通常不会通过配置中心去读取,因此,将单一配置文件拆分为多个配置文件之后,本地测试如何让SpringBoot加载这些配置文件就是我们要解决的问题。
本篇将介绍两种加载自定义配置文件的实现方式,并通过分析源码了解SpringBoot加载配置文件的流程,从而加深理解。
SpringBoot加载配置文件的原理
要实现加载自定义yml文件,我们先要了解SpringBoot是在何时,以及如何加载application-xx.yml配置文件的,为什么配置spring.profiles.active就能导入相应的配置文件。
通过猜测,配置文件的加载应该在容器初始化之前,因为我们经常会在Configuration中就要使用到一些配置,如果在Configuration开始工作之前,配置还没有加载,必然会抛出异常。
根据猜测,我们找到SpringApplication#run方法,如下图所示。
SpringBoot在创建ApplicationContext之前,会先调用prepareEnvironment方法准备创建容器所需要的环境,即创建Environment,并加载配置到Environment。这个过程中还会调用SpringApplicationRunListeners#environmentPrepared方法发布Environment准备事件。
执行上图中画线的代码最终会调用EventPublishingRunListener#environmentPrepared方法,该方法广播一个ApplicationEnvironmentPreparedEvent事件(事件同步广播同步消费),只要实现ApplicationListener接口并且订阅ApplicationEnvironmentPreparedEvent事件的订阅者都会接收到该事件,onApplicationEvent方法被调用。
由于Spring实现事件的发布订阅是同步的,在不清楚到底有多少个ApplicationEnvironmentPreparedEvent事件订阅者