SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里

问题引入

SpringCloud 有两个配置文件:

  • application.properties
  • bootstrap.properties

那么 spring.application.name = MyApp 应该配置在哪个文件中呢?
也许一部分人认为配置在哪个文件里都可以,因为两个文件是互补的;
但对于追求细节的人来说,比如上下文的 id ,就需要研究一下了。

版本信息

  • SpringCloud:Greenwich.RC2
  • SpringBoot:2.1.2.RELEASE
  • 引入 Web 模块

测试示例

  1. application.properties 配置 spring.application.name = Jingdong
    bootstrap.properties 不配
    测试结果:
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第1张图片

  2. bootstrap.properties 配置 spring.application.name = Taobao
    application.properties 不配
    测试结果:
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第2张图片

  3. application.properties 配置 spring.application.name = Jingdong
    bootstrap.properties 配置 spring.application.name = Taobao
    测试结果:
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第3张图片

结果分析:

  1. 对于环境变量来说,两个配置文件是互补的,并且 application.properties 会覆盖 bootstrap.properties 中的配置;
  2. 对于 SpringCloud 上下文来说,代码中显示设置了其 id = "bootstrap",后面会介绍如何修改 id
  3. 对于 SpringBoot 上下文来说,它的 id 只跟 bootstrap.properties 中配置的 spring.application.name 有关:如果不配,则默认 id = "application-1"(1 是自增数);如果配了 "Taobao",则 id="Taobao-1" 。不论 application.properties 是否配置了 spring.application.name ,都不影响 SpringBoot 上下文的 id

源码分析

以测试示例 3 为例,我们通过时序图来一步一步分析:(整个流程过于庞大,遂将其分割为几个主要部分,每个 “黄底红字” 都代表一部分,建议点击图片放大查看)

  1. SpringBoot 流程(只关心配置文件部分)
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第4张图片
    ↓ 02_SpringCloud 流程
    ↓ 05_SpringBoot 流程 - ConfigFileApplicationListener
    ↓ 06_SpringBoot 流程 - AncestorInitializer
    ↓ 07_SpringBoot 流程 - ContextIdApplicationContextInitializer

  2. SpringCloud 流程(只关心配置文件部分)
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第5张图片
    ↓ 03_SpringCloud 流程 - ConfigFileApplicationListener
    ↓ 04_SpringCloud 流程 - ContextIdApplicationContextInitializer
    ↑ 01_SpringBoot 流程 (整个 SpringCloud 流程完毕后,包括 03 , 04)

  3. SpringCloud 流程 - ConfigFileApplicationListener
    作用:使用 OriginTrackedMapPropertySource 对象封装 bootstrap.properties 中的 K-V 值,并将其添加到 SpringCloud 的环境变量中。
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第6张图片
    ↑ 02_SpringCloud 流程

  4. SpringCloud 流程 - ContextIdApplicationContextInitializer
    作用:a. 创建一个 ContextId 对象,其 id = "Taobao-1"; b. 设置 SpringCloud 上下文(AnnotationConfigApplicationContext)的属性 id = "Taobao-1"
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第7张图片
    ↑ 02_SpringCloud 流程

  5. SpringBoot 流程 - ConfigFileApplicationListener
    作用:使用 OriginTrackedMapPropertySource 对象封装 application.properties 中的 K-V 值,并将其添加到 SpringBoot 的环境变量中。
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第8张图片
    ↑ 01_SpringBoot 流程

  6. SpringBoot 流程 - AncestorInitializer
    作用:a. 将封装了 bootstrap.propertiesOriginTrackedMapPropertySource 直接添加到 SpringBoot 上下文的环境变量中; b. 将 SpringCloud 上下文 设置为 SpringBoot 上下文的双亲
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第9张图片
    ↑ 01_SpringBoot 流程

  7. SpringBoot 流程 - ContextIdApplicationContextInitializer
    作用:从 ContextId 对象中取出属性 id = "Taobao-1" ,设置 SpringBoot 上下文(AnnotationConfigServletWebServerApplicationContext)的属性 id = "Taobao-1"
    SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第10张图片
    分析结束。
    附一张整合的时序图:

分析总结

  • SpringBoot 上下文的属性 id 的设置流程大致是这样的:

    bootstrap.propertiesContextId 对象SpringBoot上下文的属性 id

  • 可以看到 application.properties 并没有参与到其中

拓展

其实我们可以自定义 SpringBoot 或 SpringCloud 上下文的属性 id

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

		SpringApplication springApplication = new SpringApplication(Application.class);
		ConfigurableApplicationContext context = springApplication.run(args);
		
		// 设置 SpringBoot 上下文的属性 id
		context.setId(context.getEnvironment().getProperty("spring.application.name"));

        AnnotationConfigApplicationContext parent = (AnnotationConfigApplicationContext) context.getParent();
        // 设置 SpringCloud 上下文的属性 id
        parent.setId(parent.getEnvironment().getProperty("spring.application.name"));
    }

结果:
SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里_第11张图片

结束语

spring.application.name 配置在哪个文件里,影响的只是 SpringBoot 上下文的属性 id,不会影响到环境变量的取值过程。

  1. 如果你有强迫症,看着小尾巴 -1 不舒服,而且还不太懒,那就手动编写代码设置上下文 id;
  2. 如果你有点儿强迫症,但是有点儿懒,那就把 spring.application.name 配置到 bootstrap.properties 中;
  3. 如果你既没有强迫症,又很懒,Then wherever .

你可能感兴趣的:(SpringCloud 源码分析 - spring.application.name 放到哪个配置文件里)