本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力。
为了让同一个 Spring Boot 可以在不同的环境下运行,Spring 允许开发者将配置以各种方式外部华。我们可以使用诸如属性文件、YAML 文件、命令行参数、系统环境变量等作为 Spring Boot 应用程序的配置源。
配置中的属性可以通过如下方式注入到 Bean 中:
@Value
注解的属性- Spring Framework 的
Environment
抽象 - 通过
@ConfigurationProperties
绑定的结构化对象
Spring 通过特定的 PropertySource
优先级加载配置,并允许优先级高的配置覆盖优先级低的配置。
配置加载优先级
以下是 Spring 加载配置资源的优先级(从低到高):
- Spring Boot 的默认属性,通过
SpringApplication
类中的setDefaultProperties
方法执行。 @Configuration
类上的@PropertySource
指定的配置来源。- 属性配置文件。这个是最常用的配置来源,不同的配置文件也是存在优先级关系的。(见下文)
- 属性
random.*
中的RandomValuePropertySource
。比如random.int
可以随机取一个 int 类型的随机值。 - 操作系统的环境变量。
- Java 系统属性
System.getProperties()
,就是在java -D
命令中指定的一些属性。 java:comp/env
中的 JNDI 属性ServletContext
初始化参数ServletConfig
初始化参数SPRING_APPLICATION_JSON
(环境变量和系统参数中的内联 JSON)中的属性,在 Spring 启动的时候会被解析并添加到Environment
中。具体的配置方式有以下几种:- 将
SPRING_APPLICATION_JSON
作为一个环境变量。 - 将
spring.application.json
作为系统属性,如java -Dspring.application.json='{"name": "Tom"}' -jar app.jar
。 - 将
spring.application.json
作为命令行参数,如java -jar app.jar --spring.application.json='{"name": "Tom"}'
。
- 将
- 命令行参数,也是比较常用的配置来源之一,比如
--server.port=8888
,Spring 会把指定的配置添加到Environment
中,如果不希望将命令行属性添加进去,可以通过SpringApplication.setAddCommandLineProperties(false)
禁用它们。 - 测试类的
@SpringBootTest
注解中的properties
属性。 - 测试类的
@TestPropertySource
执行的配置来源。 - DevTools 的全局设置属性,当 DevTools 启用的时候会生效,在
$HOME/.config/spring-boot
目录下。
属性配置文件
在以上的第三点,提到了属性配置文件,这是开发者最常用的配置来源,每个 Spring Boot 应用中都会有大量的配置项在属性配置文件当中。属性配置文件之间也是有区分的,它们同样存在优先级数据,当同样的属性名配置了不同属性值的时候,优先级高的会覆盖优先级低的,以下顺序从低到高:
- 打包进 jar 的
application.properties
或application.yaml
文件。 - 打包进 jar 的
application-{profile}.properties
或application-{profile}.yaml
文件。 - jar 之外的
application.properties
或application.yaml
文件。 - jar 之外的
application-{profile}.properties
或application-{profile}.yaml
文件。
在这里,推荐在一个 Spring Boot 应用中保持一致的属性配置文件格式。如果同一个应用中同时存在 .properties
和 .yaml
格式的属性配置文件,则 .properties
配置文件的优先级更高。
Spring 会从以下几个位置查找属性配置文件(优先级从低到高):
- 类路径
- 类路径下的
config
包 - 当前目录
- 当前目录的
config
目录 - 当前目录的
config
目录下的直接子目录
如果不喜欢 application
这个配置文件的名字,可以手动指定:
java -jar app.jar --spring.config.name=myconfig
配置文件的位置也是可以指定的:
java -jar app.jar --spring.config.location=\
optional:classpath:/myconfig.properties
上面的指令中,optional:
的意思是,指定的位置不一定存在这个文件。后面的配置文件路径,如果需要配置多个路径,使用 ,
隔开即可。