Spring Boot允许外部化配置,以便在不同环境中使用相同的应用程序代码。 可以使用属性文件、YAML文件、环境变量和命令行参数来外部化配置。可以使用@Value注释将属性值直接注入到bean中,通过Spring的Environment抽象访问或通过@ConfigurationProperties绑定到结构化对象。
Spring Boot使用一个非常特殊的PropertySource命令,旨在允许合理地覆盖值。 按以下顺序考虑属性:
- 在用户目录上全局设置属性(当devtools处于活动状态时,〜/.spring-boot-devtools.properties)。
- 测试中的@TestPropertySource注解。
- 测试中的@SpringBootTest注解的properties属性。
- 命令行参数。
- SPRING_APPLICATION_JSON中的属性(嵌入在环境变量或系统属性中的内联JSON)。
- ServletConfig初始化参数。
- ServletContext初始化参数。
- 来自java:comp/env的JNDI属性。
- Java系统属性(System.getProperties())。
- 系统环境变量。
- RandomValuePropertySource的random.*属性。
- 打包jar之外的特定于配置文件的应用程序属性(application-{profile}.properties和YAML变体)
- 打包在jar中的特定于配置文件的应用程序属性(application-{profile}.properties和YAML变体)
- 打包jar之外的应用程序属性(application.properties和YAML变体)。
- 打包在jar中的应用程序属性(application.properties和YAML变体)。
- @Configuration类上的@PropertySource注解。
- 默认属性(使用SpringApplication.setDefaultProperties指定)。
为了提供一个具体的例子,假设开发了一个使用name属性的@Component:
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
在应用程序类路径上(例如在jar中),可以通过application.properties提供name属性值。 在新环境中运行时,可以在jar之外提供覆盖名称的application.properties; 对于一次性测试,可以使用特定的命令行开关启动(例如java -jar app.jar --name =“Spring”)。
注:可以在命令行上使用环境变量提供SPRING_APPLICATION_JSON属性。 例如在UN * X shell中:
$ SPRING_APPLICATION_JSON ='{"foo":{"bar":"spam"}}' java -jar myapp.jar
在此示例中,将在Spring环境中使用foo.bar = spam。 还可以在System变量中将JSON作为spring.application.json提供:
$ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar
或者命令上参数:
$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'
或一个JNDI变量:
java:comp/env/spring.application.json
1. 配置随机数
RandomValuePropertySource对于注入随机值(例如秘钥或测试用例)非常有用。 它可以产生整数,长整数,uuid或字符串,例如:
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
random.int *语法是OPEN value (,max)CLOSE,其中OPEN、CLOSE是任何字符,value和max是整数。 如果提供max参数,则value是最小值,max是最大值(不包括max)。
2. 访问命令行参数
默认情况下,SpringApplication会将任何命令行选项参数(以' - '开头,例如--server.port = 9000)转换为属性并将其添加到Spring Environment中。 如上所述,命令行属性优先于其他属性源。
如果不希望将命令行属性添加到Environment中,可以使用SpringApplication.setAddCommandLineProperties(false)禁用它们。
3. Application属性文件
SpringApplication将从以下位置的application.properties文件加载属性,并将它们添加到Spring环境中:
- 当前目录下的/config子目录
- 当前目录
- classpath下的/config包
- classpath根目录
列表按优先级排序(在列表中较高位置定义的属性将覆盖在较低位置中定义的属性)。可以使用YAML(.yml)文件替代.properties文件。
如果不喜欢application.properties作为配置文件名,则可以通过指定spring.config.name环境属性来切换到另一个。 还可以使用spring.config.location环境属性(以逗号分隔的目录位置列表或文件路径)来显式的引用位置。
$ java -jar myproject.jar --spring.config.name=myproject
或
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
注:spring.config.name和spring.config.location很早就用来确定必须加载哪些文件,因此必须将它们定义为环境属性(通常是OS env,系统属性或命令行参数)。
如果spring.config.location包含目录(而不是文件),则它们应该以/结尾(并且在加载之前将附加从spring.config.name生成的名称,包括特定于配置文件的文件名)。 spring.config.location中指定的文件按原样使用,不支持特定于配置文件的变体,并且将被任何特定于配置文件的属性覆盖。
以相反的顺序搜索配置位置。 默认情况下,配置的位置是classpath:/,classpath:/config/,file:/,file:./config/。 生成的搜索顺序为:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
配置自定义配置位置时,除默认位置外,还会使用它们。 在默认位置之前搜索自定义位置。 例如,如果配置了自定义位置classpath:/custom-config/,file:./custom-config/,则搜索顺序将变为:
- file:./customer-config/
- classpath:custom-config/
- file:./config/
- file:./
- classpath:/config/
- classpath:/
此搜索顺序允许在一个配置文件中指定默认值,然后有选择地覆盖另一个配置文件中的值。 可以在application.properties(或使用spring.config.name选择的任何其他基本名称)中的某个默认位置为应用程序提供默认值。 然后,可以在运行时使用位于其中一个自定义位置的不同文件覆盖这些默认值。
注:
- 如果使用环境变量而不是系统属性,则大多数操作系统都不允许使用句点分隔的key,但可以使用下划线(例如SPRING_CONFIG_NAME而不是spring.config.name)。
- 如果在容器中运行,则可以使用JNDI属性(在java:comp/env中)或servlet上下文初始化参数来代替环境变量或系统属性。
4. 特定于配置文件的属性
除了application.properties文件之外,还可以使用命名约定application-{profile}.properties定义特定于配置文件的属性。 环境具有一组默认配置文件(默认情况下为[默认]),如果未设置活动配置文件,则使用这些配置文件(即,如果未显式激活配置文件,则加载application-default.properties中的属性)。
特定于配置文件的属性从与标准application.properties相同的位置加载,特定于配置文件的文件始终覆盖非特定的文件,而不管特定于配置文件的文件是在打包的jar内部还是外部。
如果指定了多个配置文件,则应用最后获胜策略。 例如,spring.profiles.active属性指定的配置文件是在通过SpringApplication API配置的配置文件之后添加的,因此优先。
注:如果在spring.config.location中指定了任何文件,则不会考虑这些文件的特定于配置文件的变体。 如果您还想使用特定于配置文件的属性,请使用spring.config.location中的目录。
5. 属性中的占位符
application.properties中的值在使用时会通过现有环境进行过滤,因此您可以返回先前定义的值(例如,来自系统属性)。
app.name=MyApp
app.description=${app.name} is a Spring Boot application
注:您还可以使用此技术创建现有Spring Boot属性的“简短”变体。 有关详细信息,请参见第72.4节“使用'短'命令行参数”操作方法。