Spring Boot 配置优先级

本文探讨了Spring Boot和Spring Cloud中配置的优先级,分析了不同配置来源(如命令行参数、jar包内外的application.properties)的加载顺序。通过实例测试和源码解析,揭示了配置读取的优先级,指出命令行参数优先级高于内部配置文件,分布式配置中心配置优先级最高。文章还详细解析了配置加载的源码流程。
摘要由CSDN通过智能技术生成

参考资料:
Sprinb Boot 2.1.5.RELEASE 官方文档

Spring framework 5.1.9.RELEASE 官方文档

配置中心以 Spring Cloud Config 作为展开

前置问题

在以Spring Boot 和 Spring Cloud 作为技术栈的开发中,针对应用的配置最常见用的就是三种配置,

  • classpath 下的 application.properties
  • commandline-args :命令行参数,通过 java命令启动应用时指定的入参
  • 以及分布式系统中的分布式配置中心

假设此时:在这三个配置中,同时存在一个配置:ext-info=XX 。那么 在程序运行时,究竟那么配置会生效?

先来看看 Spring Boot 提供外部化配置

Externalized Configuration

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments.You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration.Property values can be injected directly into your beans by using the @Value annotation, accessed through Spring’s Environment abstraction, or be bound to structured objects through @ConfigurationProperties.

大意如下

为了使得同一套代码,能够在不同的配置环境下运行, Spring Boot 提供了多种配置外部化的能力,同时这几种配置方式能够共存。
这几种外部化配置存在的形式,包括 properties 文件、YML 文件、环境变量、命令行参数等。
在程序中,开发者可以通过 @Value 注解,直接引用 Environment 对象,或者通过 @ConfigurationProperties注解等方式对这些外部化配置进行读取,灵活的变更程序配置。

配置信息分布在不同位置不同文件中,使得配置更灵活,但必然会带来一个问题:不同配置文件中存在同一个属性配置(如:ext-info=XXX),应用程序在运行中会以哪个配置文件的配置作为其运行配置?

针对这个问题,Spring Boot 官方给出了说明文档,在多种配置文件共存的情况下,应用程序会选择哪个配置文件的属性配置作为运行配置(读取优先级:由高到低

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
  2. @TestPropertySource annotations on your tests.
  3. properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.
  4. Command line arguments.
  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
  6. ServletConfig init parameters.
  7. ServletContext init parameters.
  8. JNDI attributes from java:comp/env.
  9. Java System properties (System.getProperties()).
  10. OS environment variables.
  11. A RandomValuePropertySource that has properties only in random.*.
  12. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
  13. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
  14. Application properties outside of your packaged jar (application.properties and YAML variants).
  15. Application properties packaged inside your jar (application.properties and YAML variants).
  16. @PropertySource annotations on your @Configuration classes.
  17. Default properties (specified by setting SpringApplication.setDefaultProperties).

实例测试其中几种常见配置方式的优先级顺序

测试的配置方式如下

  • 优先级 4 的 Command line arguments :命令行参数配置
  • 优先级 12 的 jar包外部的 application.properties
  • 优先级 13 的 jar 包内部的 application.properties(默认:classpath 下的 application.properties)

一、环境准备

  • 运行环境
    spring Boot 2.1.5.RELEASE Web 应用

  • 准备测试的属性配置
    ext-info=XXX

  • 提供 API,用来读取 ext-info 配置信息

    @Value("${ext-info}")
    private String extInfo;
    
    /** http://localhost:9527/ext-info **/
    @RequestMapping("/ext-info")
    public String extInfo(){
         
    	return extInfo;
    }
    
  • 通过 /actuator/env 端点,获取当前应用存在的多种配置文件信息

二、优先级测试

测试一、 【优先级 4 】Command line arguments(命令行配置) VS 【优先级 13 】application.properties(jar 包内部默认配置文件)
  • **step1、**在 jar 包内部,src/main/resource 中的 application.properties 文件中增加测试配置 主要配置

    # 内部配置文件
    ext-info = info-inside-jar
    
  • **step2、**运行 jar 程序,同时指定命令行参数 –ext-info=commandLineArgs

    java -jar ext-configuration-0.0.1-SNAPSHOT.jar --ext-info=commandLineArgs

  • **step3、**访问 自定义API、和 actuator env 端点

    • 自定义 API 访问 curl “http://localhost:9527/ext-info”
      结果:commandLineArgs
    • actuator env 端点
      在这里插入图片描述
  • 结论
    Command line arguments(命令行配置) 配置属性优先级比 **application.properties(jar 包内部默认配置文件)**高,两者存在同一个属性配置时,以 Command line arguments(命令行配置) 配置为主。

测试二、 【优先级 13】 application.properties(jar 包内部默认配置文件)VS【优先级 12】 application-outside.properteis(jar包外部配置文件)配置 优先级
  • **step1、**外部配置文件 application-outside.properties 主要配置

    # 外部配置文件
    ext-info = outside-jar
    

    在 运行 jar 程序时,通过命令行参数的方式指定外部配置文件 –spring.config.location=XXX

  • **step2、**jar 包内配置文件 application.properteis 主要配置(同测试一)

    # 内部配置文件
    ext-info = info-inside-jar
    
  • **step3、**运行 jar 程序
    java -jar ext-configuration-0.0.1-SNAPSHOT.jar --spring.config.location=.xxxxx/application-outside.properties

  • **step4、**访问 自定义API、和 actuator env 端点

    • 自定义 API 访问 curl “http://localhost:9527/ext-info”
      结果:outside-jar
    • actuator env 端点
      在这里插入图片描述
  • 结论
    application-outside.properteis(jar包外部配置文件) 配置属性读取优先级比 application.properties(jar 包内部默认配置文件) 高。两者存在同一配置属性时,以外部配置文件的属性配置为主。

    命令行指定了外部配置文件:jar包内的 application.properties 以及 bootstrap.properties 文件将不再被加载

测试三、【优先级 4 】 Command line arguments(命令行配置)、【优先级 13】application.properties(jar 包内部默认配置文件) 、【优先级12】 application-outside.properteis(jar包外部配置文件)配置 优先级

这里不进行测试流程展示,通过测试一和测试二能够得出,三者的优先级由高到低依次为:Command line arguments(命令行配置) > application-outside.properteis(jar包外部配置文件) > application.properties(jar 包内部默认配置文件)

更多内容,参考官方文档

源码分析:Command line arguments(命令行配置)和 内部配置文件 为例,分析 Spring Boot 如何实现配置读取的优先级。

前置概念

分析之前,先来看看 Spring Boot 应用的环境上下文 Environment。引用Spring Framework 官方对于 Environemtn 的说明:

The Environment interface is an abstraction integrated in the container that models two key aspects of the application environment:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值