[翻译]Spring Boot 特征参考2——外部配置:上
本文翻译自:http://docs.spring.io/spring-boot/docs/2.0.0.M2/reference/htmlsingle/
详细介绍Spring boot的关键特征,针对有一定springboot基础的同学。
目录
- 1 外部配置
- 1.1 配置随机值
- 1.2 访问命令行属性
- 1.3 应用程式属性档案
- 1.4 配置文件特定的属性
- 1.5 properties中的占位符
- 1.6 使用YAML而不是properties
- 1.6.1 加载YAML
- 1.6.2 将YAML作为Spring环境中的属性
- 1.6.3 多个YAML文件
- 1.6.4 YAML的缺点
- 1.6.5 合并YAML列表
1. 外部配置
Spring Boot允许您外部化配置,以便在不同的环境中使用相同的应用程序代码。您可以使用属性文件,YAML文件,环境变量和命令行参数来外部化配置。可以使用@Value注释将属性值直接注入到您的bean中,通过Spring的Environment抽象访问或通过@ConfigurationProperties绑定到结构化对象。
Spring Boot使用非常特殊的PropertySource命令,旨在允许明智地覆盖值。属性按以下顺序考虑:
- Devtools全局设置属性在您的主目录(~/.spring-boot-devtools.properties当devtools是活动的)。
- @TestPropertySource注释在你的单元测试中。
- @SpringBootTest #properties 注解属性在你的单元测试中。
- 命令行参数。
- 来自SPRING_APPLICATION_JSON的属性(嵌入在环境变量或系统属性中的内嵌JSON)
- *ServletConfig *init参数。
- *ServletContext *init参数。
- 来自java的JNDI属性:java:comp/env。
- Java系统属性(System.getProperties())。
- OS环境变量。
- 一个RandomValuePropertySource,只有随机的属性。
- 特定于应用程序的应用程序属性在打包的jar之外(application- {profile} .properties和YAML变量)。
- 封装在jar中的配置文件特定的应用程序属性(application- {profile} .properties和YAML变量)。
- 您的打包的jar(application.properties和YAML变量)之外的应用程序属性。
- 应用程序属性打包在你的jar中 (application.properties和YAML变量)。
- @PropertySource注释在您的@Configuration类。
- 默认属性(使用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来覆盖该name;对于一次性测试,您可以使用特定的命令行开关启动(例如,java -jar app.jar --name =“Spring”)。
注意:
SPRING_APPLICATION_JSON属性可以在命令行中提供一个环境变量。例如在UN * X shell中:
$ SPRING_APPLICATION_JSON ='{“foo”:{“bar”:“spam”}}'java -jar myapp.jar
在这个例子中,你将在springEnvironment中以foo.bar=spam结尾。您还可以在系统变量中将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.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是任何字符和值,max是整数。如果提供max,则值为最小值,max为最大值(仅包含)。
1.2 访问命令行属性
默认情况下,SpringApplication将任何命令行选项参数(以' - '开头,例如--server.port = 9000)转换为property,并将其添加到Spring的Environment中。
如上所述,命令行属性始终优先于其他属性源。如果不希望将命令行属性添加到Environment中,可以使用SpringApplication.setAddCommandLineProperties(false)禁用它们。
1.3 应用程式属性档案
SpringApplication将从以下位置的application.properties文件中加载属性,并将它们添加到当前目录的Spring Environment:
- 一个/ config子目录中。
- 当前目录
- 一个 classpath /config 保中
- 类路径根
列表按优先级排序(在列表中定义的属性中定义的属性将覆盖在较低位置中定义的位置)。
注意:您也可以使用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,system属性或命令行参数)。
如果spring.config.location包含目录(而不是文件),它们应该以/结束(并将在加载之前附加从spring.config.name生成的名称,包括特定于文件的文件名)。在spring.config.location中指定的文件按原样使用,没有支持特定于配置文件的变量,并且将被任何特定于配置文件的属性覆盖。
默认的搜索路径classpath:,classpath:/ config,file:,file:config /始终被使用,不管spring.config.location的值如何。 此搜索路径从最低优先级排序(file:config / 最高优先级)。
如果您指定自己的位置,则它们优先于所有默认位置,并使用相同的最低到最高优先级排序。 这样,您可以在application.properties(或使用spring.config.name选择的其他基础名称)中为应用程序设置默认值,并在运行时使用不同的文件覆盖它,并保留默认值。
注意:如果使用环境变量而不是系统属性,则大多数操作系统不允许使用周期分隔的键名称,但可以使用下划线(例如SPRING_CONFIG_NAME,而不是spring.config.name)。
注意:如果你在一个容器中运行JNDI属性(在java:comp / env)或者servlet 可以使用上下文初始化参数来代替环境变量或系统属性。
1.4 配置文件特定的属性
除了application.properties文件之外,还可以使用命名约定application- {profile} .properties定义特定于配置文件的属性。Environment具有默认配置文件(默认为[default]),如果没有设置活动配置文件(即,如果没有显式激活配置文件,则加载了来自application-default.properties的属性)。
配置文件特定的属性从与标准application.properties相同的位置加载,配置文件特定的文件始终覆盖非特定的文件,而不管特定于配置文件的文件是否在打包的jar内部或外部。
如果指定了几个配置文件,则应用最后一个优先策略。例如,由spring.profiles.active属性指定的配置文件通过SpringApplication API配置后添加,因此优先。
注意:如果您在spring.config.location中指定了任何文件,则不会考虑这些文件的特定于配置文件的变量。使用 如果还要使用特定于配置文件的属性,请在spring.config.location中指定目录。
1.5 properties中的占位符
application.properties中的值通过使用现有Environment进行过滤,以便您可以参考以前定义的值(例如,从系统属性)。
app.name = MyApp
app.description = $ {app.name} is a Spring Boot application
您还可以使用此技术创建现有Spring Boot属性的“简短”变体。
1.6 使用YAML而不是properties
YAML是JSON的超集,因此这是一种用于指定分层配置数据的非常方便的格式。只要您的类路径中有SnakeYAML库,SpringApplication类将自动支持YAML作为属性的替代方法。
注意:如果您使用“Starters”,SnakeYAML将通过spring-boot-starter自动提供。
1.6.1 加载YAML
Spring Framework提供了两个可用于加载YAML文档的方便类。 YamlPropertiesFactoryBean将加载YAML作为Properties,并且YamlMapFactoryBean将加载YAML作为Map。例如,以下YAML文档:
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
将被转换成这些属性:
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML列表表示为具有[index]取消引用的属性键,例如YAML:
my:
servers:
- dev.bar.com
- foo.bar.com
将被转换成这些属性:
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
要使用Spring DataBinder实用程序(这是@ConfigurationProperties所做的)绑定到这样的属性,您需要在类型为java.util.List(或Set)的目标bean中具有一个属性,并且您需要提供一个setter,或者用可变值初始化它,例如这将绑定到上面的属性
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
注意:
配置列表时,需要特别小心,因为覆盖方式将无法正常工作。在上面的例子中,当我的几个地方重新定义my.servers时,单个元素的目标是覆盖,而不是列表。要确保具有较高优先级的PropertySource可以覆盖列表,您需要将其定义为单个属性:
my:
servers: dev.bar.com,foo.bar.com
1.6.2 将YAML作为Spring环境中的属性
可以使用YamlPropertySourceLoader类在SpringEnvironment中将YAML作为PropertySource进行公开。这允许您使用熟悉的@Value注释和占位符语法来访问YAML属性。
1.6.3 多个YAML文件
您可以使用spring.profiles键指定单个文件中的多个配置文件特定的YAML文档,以指示文档何时应用。例如:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
在上面的示例中,如果development配置文件处于活动状态,则server.address属性将为127.0.0.1。如果development和production配置文件未启用,则该属性的值将为192.168.1.100。
如果应用程序上下文启动时没有显式激活,默认配置文件将被激活。所以在这个YAML中,我们为security.user.password设置一个仅在“默认”配置文件中可用的值:
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak
而在此示例中,由于密码未附加到任何配置文件,因此始终设置密码,必要时必须在所有其他配置文件中显式重置密码:
server:
port: 8000
security:
user:
password: weak
使用“spring.profiles”元素指定的弹簧轮廓可以选择使用!字符。如果为单个文档指定了否定和非否定的配置文件,则至少有一个非否定配置文件必须匹配,没有否定配置文件可能匹配。
1.6.4 YAML的缺点
不能通过@PropertySource注释来加载YAML文件。因此,在需要以这种方式加载值的情况下,需要使用属性文件。
1.6.5 合并YAML列表
如上所述,任何YAML内容最终都转化为属性。当通过配置文件覆盖“列表”属性时,该过程可能是直观的。
例如,假设默认情况下,name和description属性为null的MyPojo对象。让我们从FooProperties中公开MyPojo的列表:
@ConfigurationProperties("foo")
public class FooProperties {
private final List<MyPojo> list = new ArrayList<>();
public List<MyPojo> getList() {
return this.list;
}
}
请考虑以下配置:
foo:
list:
- name: my name
description: my description
---
spring:
profiles: dev
foo:
list:
- name: my another name
如果dev配置文件不活动,FooProperties.list将包含一个如上定义的MyPojo条目。如果启用了dev配置文件,list仍将只包含一个条目(名称为“我的另一个名称”,描述为null)。此配置不会将第二个MyPojo实例添加到列表中,它不会合并项。
foo:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
foo:
list:
- name: my another name
在上面的示例中,考虑到dev配置文件处于活动状态,FooProperties.list将包含一个MyPojo实体(包含名称为“my another 描述为null)。
当在多个配置文件中指定集合时,将使用具有最高优先级的集合(并且仅使用该集合):