Springboot源码解析之Environment

前言:springboot近些年已经逐渐成为新项目的必备框架。Springboot可以只使用几行代码就可以帮我们搭建一个可运行的项目框架。Springboot的自定义配置也是非常简单,只需要遵循规范在application.yml或application.properties中添加配置,就可以在代码中使用@Value获取到配置。那么springboot就的合适加载的自定义配置?自定义配置又是存储在哪里的呢?

Springboot的启动类很简单,一行代码就搞定。

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

要想搞清楚上面两个问题我们只能从springboot的源码中寻找答案。

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
   // 获取监听器
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.starting();
   try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      // 准备运行环境
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
      configureIgnoreBeanInfo(environment);
      Banner printedBanner = printBanner(environment);
      // 创建应用上下文
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
   }

   try {
      listeners.running(context);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

通过不断的猜测与debug尝试,可以发现,在执行完prepareEnvironment后,environment对象中可以找到application.properties中的配置。

到这里我们知道配置存储的位置了。仔细观察可以发现environment中同时存储了项目的启动变量以及操作系统的环境变量等。

配置文件的具体加载流程请看下面的时序图:

 

从时序图可以看出加载的流程是很简单的,但其中涉及到监听器、Environment的后置处理器、属性源加载器等组件。以及springboot的SPI机制

ConfigFileApplicationListener:既是事件监听器同时也是Environment的后置处理器

PropertySourceLoader:两个实现类PropertiesPropertySourceLoader,YamlPropertySourceLoader它们分别实现properties、yml文件的加载。

理解springboot配置加载流程后,我们想加载远程配置(统一配置中心)的时候可以通过SPI机制自定义Environment后置处理器实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#朱守成#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值