SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

bootstrap.yml(bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取,如可以使用来配置application.yml中使用到参数等

application.yml(application.properties) 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。

加载过程中,配置文件加载顺序为:
bootstrap.yml > application.yml > application-dev(prod).yml

通过对代码进行Debug发现SpringApplication#run(…)方法被调用了3次。

项目结构:

SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

监控加载的配置文件,断点设置在:ConfigFileApplicationListener#load(…) 501行,可以监控都读取了哪些配置文件。

SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

最终监控到执行SpringApplication#run(args)的顺序:

SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

1)第一次SpringApplication#run() args为{}

SpringBoot入口类

@SpringBootApplication(scanBasePackages = {"com.dx"}, proxyBeanMethods = false)
@EnableFeignClients(basePackages = {"com.dx.domain.feign"})
@EnableShackleTemplates(basePackages = {"com.dx.service"})
@EnableEurekaClient
public class App {
    /**
     * 主程序入口(jar格式)
     * @param args 命令行参数
     * @throws Exception 执行异常
     */
    public static void main(String[] args) throws Exception {
        configureApplication(new SpringApplicationBuilder()).run(args);
    }

    /**
     * 定义程序入口
     * @param builder SpringApplicationBuilder
     * @return SpringApplicationBuilder
     */
    private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
        return builder.sources(App.class).bannerMode(Banner.Mode.CONSOLE).logStartupInfo(true)
                      .registerShutdownHook(true).web(WebApplicationType.SERVLET);
    }
}

2)第一次SpringApplication#run()执行到SpringApplication#prepareEnvironment(…)执行第二次SpringApplication#run()

返回context:

org.springframework.context.annotation.AnnotationConfigApplicationContext@7876d598, started on Tue Mar 13 11:10:31 CST 2021

SpringApplication#run(String… args)运行流程:

SpringApplication#run(String... args)
|-ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
SpringApplication#prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments)
|-listeners.environmentPrepared((ConfigurableEnvironment)environment);
SpringApplicationRunListeners#environmentPrepared(ConfigurableEnvironment environment)
|-listener.environmentPrepared(environment);
EventPublishingRunListener#environmentPrepared(ConfigurableEnvironment environment)
|-this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
SimpleApplicationEventMulticaster#multicastEvent(ApplicationEvent event)
|-constructor(...)
SimpleApplicationEventMulticaster#multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType)
|-this.invokeListener(listener, event);
SimpleApplicationEventMulticaster#invokeListener(ApplicationListener listener, ApplicationEvent event)
|-this.doInvokeListener(listener, event);
SimpleApplicationEventMulticaster#doInvokeListener(ApplicationListener listener, ApplicationEvent event)
|-listener.onApplicationEvent(event);
BootstrapApplicationListener#onApplicationEvent(ApplicationEnvironmentPreparedEvent event)
|-context = this.bootstrapServiceContext(environment, event.getSpringApplication(), configName);
BootstrapApplicationListener#bootstrapServiceContext(ConfigurableEnvironment environment, final SpringApplication application, String configName)

BootstrapApplicationListener#bootstrapServiceContext(…)源码分析:

private ConfigurableApplicationContext bootstrapServiceContext(ConfigurableEnvironment environment, final SpringApplication application, String configName) {
    StandardEnvironment bootstrapEnvironment = new StandardEnvironment();
    MutablePropertySources bootstrapProperties = bootstrapEnvironment.getPropertySources();
    Iterator var6 = bootstrapProperties.iterator();
    while(var6.hasNext()) {
        PropertySource source = (PropertySource)var6.next();
        bootstrapProperties.remove(source.getName());
    }

    String configLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.location:}");
    String configAdditionalLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.additional-location:}");
    Map bootstrapMap = new HashMap();
    bootstrapMap.put("spring.config.name", configName);
    bootstrapMap.put("spring.main.web-application-type", "none");
    if (StringUtils.hasText(configLocation)) {
        bootstrapMap.put("spring.config.location", configLocation);
    }

    if (StringUtils.hasText(configAdditionalLocation)) {
        bootstrapMap.put("spring.config.additional-location", configAdditionalLocation);
    }

    bootstrapProperties.addFirst(new MapPropertySource("bootstrap", bootstrapMap));
    Iterator var9 = environment.getPropertySources().iterator();

    while(var9.hasNext()) {
        PropertySource source = (PropertySource)var9.next();
        if (!(source instanceof StubPropertySource)) {
            bootstrapProperties.addLast(source);
        }
    }

    SpringApplicationBuilder builder = (new SpringApplicationBuilder(new Class[0])).profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF).environment(bootstrapEnvironment).registerShutdownHook(false).logStartupInfo(false).web(WebApplicationType.NONE);
    SpringApplication builderApplication = builder.application();
    if (builderApplication.getMainApplicationClass() == null) {
        builder.main(application.getMainApplicationClass());
    }

    if (environment.getPropertySources().contains("refreshArgs")) {
        builderApplication.setListeners(this.filterListeners(builderApplication.getListeners()));
    }

    builder.sources(new Class[]{BootstrapImportSelectorConfiguration.class});
    ConfigurableApplicationContext context = builder.run(new String[0]);
    context.setId("bootstrap");
    this.addAncestorInitializer(application, context);
    bootstrapProperties.remove("bootstrap");
    this.mergeDefaultProperties(environment.getPropertySources(), bootstrapProperties);
    return context;
}

监控到尝试加载资源文件:

**加载 bootstrap 文件**
file:./config/bootstrap.[properties|xml|yml|yaml]
file:./bootstrap.[properties|xml|yml|yaml]
classpath:/config/bootstrap.[properties|xml|yml|yaml]
classpath:/bootstrap.[properties|xml|yml|yaml]

**加载 bootstrap-composite 文件**
file:./config/bootstrap-composite.[properties|xml|yml|yaml]
file:./bootstrap-composite.[properties|xml|yml|yaml]
classpath:/config/bootstrap-composite.[properties|xml|yml|yaml]
classpath:/bootstrap-composite.[properties|xml|yml|yaml]

3)第一次SpringApplication#run()执行到SpringAppllication#prepareEnvironment(…)执行过程中加载在资源文件:

第一次SpringApplication#run执行过程中,SpringApplication#prepareEnvironment(…)执行过程中加载在资源文件:

application.yaml...

file:./config/application.[properties|xml|yml|yaml]
file:./application.[properties|xml|yml|yaml]
classpath:/config/application.[properties|xml|yml|yaml]
classpath:/application.[properties|xml|yml|yaml]

file:./config/application-composite.[properties|xml|yml|yaml]
file:./application-composite.[properties|xml|yml|yaml]
classpath:/config/application-composite.[properties|xml|yml|yaml]
classpath:/application-composite.[properties|xml|yml|yaml]

4)第一次SpringApplication#run()执行到SpringApplication#prepareContext(…)执行第三次SpringApplication#run()

代码执行SpringApplication#prepareContext(…)

SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

args = {String[4]@5280}
0 = “–spring.config.name=application”
1 = “–spring.cloud.bootstrap.enabled=false”
2 = “–encrypt.failOnError=false”3 = “–spring.config.location=classpath:/config/uat/”

监控到尝试加载资源文件:

**加载 application 文件**
classpath:/config/uat/application-default.[properties|xml|yml|yaml]

5)第一次SpringApplication#run()执行完,返回context

org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@784c5ef5, started on Tue Mar 13 11:16:25 CST 2021, parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@7876d598

bootstrap.yml、application.yml、application-dev.yml配置文件之间覆盖性验证:

1)如果三个文件都配置了server.port,后加载的配置覆盖前者

加载顺序:bootstrap.yml->application.yml->applicaiton-dev.yml

2)如果是nacos的配置中心,必须配置到boostrap.yml

如果是bootstrap.yml、application.yml、application-dev.yml都配置了spring.cloud.nacos.config,那么是boostrap.yml中生效。

如果是bootstrap.yml中未配置,其他两个文件配置了,也不生效。spring.cloud.nacos.config采用默认值。

Original: https://www.cnblogs.com/yy3b2007com/p/14531956.html
Author: cctext
Title: SpringBoot(十九):SpringBoot运行启动时执行3次SpringApplication#run(args)加载了哪些配置文件?以及配置文件之间的覆盖性。

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/540991/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 小蜜蜂引起的jQuery插件

    Original: https://www.cnblogs.com/chenyjccxy/p/5032662.htmlAuthor: chenyjTitle: 小蜜蜂引起的jQue…

    Java 2023年6月9日
    083
  • windows下perl的安装和脚本的运行

    https://www.aliyundrive.com/s/tFTCygW7ZUZ 直接双击运行下载的文件,首先会出现perl版本等等信息的介绍,不要理,直接next就会出现是否接…

    Java 2023年6月8日
    081
  • 记一次log4j日志导致线上OOM问题案例

    最近一个服务突然出现 OutOfMemoryError,两台服务因为这个原因挂掉了,一直在full gc。还因为这个问题我们小组吃了一个线上故障。很是纳闷,一直运行的好好的,怎么突…

    Java 2023年6月7日
    097
  • MarkDown学习

    二级标题 … +空格+标题的名字(可以写到六级标题,写几个#号就代表是几级标题) 在文字两边都加两个星号 在文字两边都加一个星号 斜体加粗 在文字两边各加三个星号 删除…

    Java 2023年6月7日
    0112
  • springcloud alibaba 集成 nacos注册中心配置使用

    pom <span class="hljs-tag"><<span class="hljs-name">pro…

    Java 2023年6月7日
    075
  • Redis阻塞

    为什么阻塞 内部原因 (1)redis采用单线程处理请求,reactor是同步IO,需要等待命令执行完成,才会返回执行结果,然后进入下一个请求(队列) (2)持久化阻塞 (3)CP…

    Java 2023年6月5日
    058
  • String 部分方法使用

    package com.Mxhlin.String; import java.util.Locale; /** * @author Mxhlin * @Email fuhua277…

    Java 2023年6月7日
    077
  • Linux下用Docker部署接口安全的运行环境

    背景:MySQL 数据库运行在宿主机上(Linux) 需求:Redis、服务、页面分别运行在独立的docker中,并处于同一网络,容器内部重要目录要挂载在物理目录,保证数据安全 方…

    Java 2023年6月8日
    096
  • 机器学习(6)K近邻算法

    k-近邻,通过离你最近的来判断你的类别 例子: 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近的样本中大多数属于某一类别),则该样本属于这个类别 K近邻需要做标准化…

    Java 2023年6月8日
    077
  • [置顶][水贴]给所有制作同人/独立游戏的同学一些建议

    趁最近搞游戏引擎系列之时给所有制作同人/独立游戏的同学一些建议 当然我想来这个BLog 80%-90% 的人都不是制作同人/独立游戏的同学。 所以说水贴一个。。。 时间: 我记得当…

    Java 2023年5月29日
    079
  • 延时任务-基于redis zset的完整实现

    所谓的延时任务给大家举个例子:你买了一张火车票,必须在30分钟之内付款,否则该订单被自动取消。 订单30分钟不付款自动取消,这个任务就是一个延时任务。 我之前已经写过2篇关于延时任…

    Java 2023年6月15日
    088
  • php判断远程文件是否存在

    php判断本地文件是否存在可以简单的使用is_file就可以实现。但是在部分情况下会检测远程文件是否存在,实现方式如下 1、可以使用fsocketopen,通过返回的状态码判断 2…

    Java 2023年6月8日
    079
  • SpringBoot集成thymeleaf增删改查示例

    有小伙伴找我要个 thymeleaf 的 demo,说自己集成的总是报错,所以就有了这篇… 关于什么是 thymeleaf 我就不赘述了,相信搜到这篇的大部分是奔着如何…

    Java 2023年5月30日
    061
  • javase集合 温故而知新

    重温javase集合 前言:1、为什么要有集合?数组长度需要在初始化时确定大小,数据结构单一、因此集合出现了 2、数组和集合的区别区别一:数组既可以存储基本数据类型,又可以存储引用…

    Java 2023年6月16日
    069
  • 【Java】【53】map的containsKey()及containsValue()方法

    前言: containsKey():map中是否包含某个key值 containsValue():map中是否包含某个value值 正文: 参考博客: Original: http…

    Java 2023年5月29日
    0103
  • 最长公共子序列

    很久之前就有研究这个算法 结果忘记上传了 哈哈 前天看到好多同学需要这个算法 所以 来吧 写一写 先来看下 什么是公共子序列 我直接来一张图 相信大家就明白了 当然 图片是百度到的…

    Java 2023年6月5日
    099
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球