springboot源码解读与原理分析_从SpringBoot源码分析 配置文件的加载原理和优先级...

本文深入探讨SpringBoot配置文件加载的原理,包括为何启动参数能覆盖配置文件中的设置。通过源码分析,揭示了StandardServletEnvironment如何处理虚拟机启动参数,并解释了配置文件的加载顺序和优先级,例如application.yml和application-dev.yml的处理方式。
摘要由CSDN通过智能技术生成


本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级
跟入源码之前,先提一个问题
SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数(VM Options)传入配置项,为什么通过启动参数传入的配置项会“顶掉”配置文件中的配置?示例
application.yml server.port: 8888 spring.profiles.active: dev
application-dev.yml
spring.think: hello在IDEA中使用命令行配置项
VM Options
-Dserver.port=5555
如下图:

75374589f0fe9fcef00c1b5817d94e5d.png

启动结果:
Tomcat started on port(s): 5555 (http) with context path ''
同时在application.yml 和 启动参数(VM options)中设置 server.port, 最终采用了 启动参数 中的值。
下面开始从main函数启动处,跟入SpringBoot源码,看看SpringBoot是如何处理的。系统说明
JDK:1.8
SpringBoot 版本: 2.0.2.RELEASE
IDE: IntelliJ IDEA 2017跟入源码正文
#ApplicationConfigLoadFlow.java public static void main(String[] args) { SpringApplication.run(ApplicationConfigLoadFlow.class, args); }
从SpringApplication.run 函数开始,一个方法一个方法的跟入源码。需要跟入的方法给与注释或高亮。IDEA 快捷键:进入方法: Ctrl + 鼠标左键光标前进/后退: Ctrl + Shirt + 右方向键/左方向键
依次跟入源码:

#SpringApplication.java return run(new Class<?>[] { primarySource }, args)
#SpringApplication.java return new SpringApplication(primarySources).run(args);
#SpringApplication.java
    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);
            configureIgnoreBeanInfo(environment);


进入public ConfigurableApplicationContext run(String... args) 方法后,我们重点看 prepareEnvironment这个方法。
这个方法之前的源码的从类名和源码注释上知道stopWatch用于计时,上下文context还未初始化,listeners监听器存储了EventPushlingRunListener。
通过IDEA 一行行debug可以看到是在 prepareEnvironment方法执行后,server.port 配置项才被加载入 environment 环境配置中。
如下图所示。注意:配置文件中的配置还未载入,请先接着往后看。

7230b474c9afb20e371607ab2f2c62a2.png


因此,我们重新打断点跟入prepareEnvironment方法。

#SpringApplication.java
    private ConfigurableEnvironment prepareEnvironment(
            SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments) {
        // Create and configure the environment
        //跟入
        ConfigurableEnvironment environment = getOrCreateEnvironment();
        configureEnvironment(environment, applicationArguments.getSourceArgs());


同样的套路,通过debug发现实在getOrCreateEnvironment方法执行后得到server.port的值

#SpringApplication.java
    private ConfigurableEnvironment getOrCreateEnvironment() {
        if (this.environment != null) {
            return this.environment;
        }
        if (this.webApplicationType == WebApplicationType.SERVLET) {
            //跟入 
            return new StandardServletEnvironment();
        }


虚拟机启动参数的加载 是在StandardServletEnvironment 的实例化过程中完成的。
跟入StandardServletEnvironm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值