Spring Boot 加载 property 顺序如下:
RandomValuePropertySource 类用于配置随机值。
示例:
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]}
默认情况下, SpringApplication 会获取 – 参数(例如 --server.port=9000 ),并将这个 property 添加到 Spring 的 Environment 中。
如果不想加载命令行属性,可以通过 SpringApplication.setAddCommandLineProperties(false) 禁用。
SpringApplication 会自动加载以下路径下的 application.properties 配置文件,将其中的属性读到 Spring 的 Environment 中。
当前目录的 /config 子目录
当前目录
classpath 路径下的 /config package
classpath 根路径
注:
以上列表的配置文件会根据顺序,后序的配置会覆盖前序的配置。
你可以选择 YAML(yml) 配置文件替换 properties 配置文件。
如果不喜欢 application.properties 作为配置文件名,可以使用 spring.config.name 环境变量替换:
$ java -jar myproject.jar --spring.config.name=myproject
可以使用 spring.config.location 环境变量指定配置文件路径:
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
如果定义 application-{profile}.properties 形式的配置文件,将被视为 profile 环境下的特定配置。
可以通过 spring.profiles.active 参数来激活 profile,如果没有激活的 profile,默认会加载 application-default.properties 中的配置。
application.properties 中的值会被 Environment 过滤,所以,可以引用之前定义的属性。
app.name=MyApp
app.description=${app.name} is a Spring Boot application
注:你可以使用此技术来创建 Spring Boot 属性变量。请参考: Section 77.4, “Use ‘Short’ Command Line Arguments
Spring 框架有两个类支持加载 YAML 文件。
示例 1
environments:
dev:
url: http://dev.example.com
name: Developer Setup
prod:
url: http://another.example.com
name: My Cool App
等价于:
environments.dev.url=http://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=http://another.example.com
environments.prod.name=My Cool App
YAML 支持列表形式,等价于 property 中的 [index] :
my:
servers:
- dev.example.com
- another.example.com
等价于
my.servers[0]=dev.example.com
my.servers[1]=another.example.com
YamlPropertySourceLoader 类会将 YAML 配置转化为 Spring Environment 类中的 PropertySource 。然后,你可以如同 properties 文件中的属性一样,使用 @Value 注解来访问 YAML 中配置的属性。
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production & eu-central
server:
address: 192.168.1.120
注:YAML 注解中的属性不能通过 @PropertySource 注解来访问。所以,如果你的项目中使用了一些自定义属性文件,建议不要用 YAML。
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
相当于支持配置以下属性:
然后,你需要使用 @EnableConfigurationProperties 注解将属性类注入配置类中。
@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}
Spring Boot 属性名绑定比较松散。
以下属性 key 都是等价的:
Property Note
acme.my-project.person.first-name
- 分隔
acme.myProject.person.firstName 驼峰命名
acme.my_project.person.first_name _ 分隔
ACME_MYPROJECT_PERSON_FIRSTNAME 大写字母
如果需要类型转换,你可以提供一个 ConversionService bean (一个名叫 conversionService 的 bean) 或自定义属性配置 (一个 CustomEditorConfigurer bean) 或自定义的 Converters (被 @ConfigurationPropertiesBinding 注解修饰的 bena)。
Spring 使用 java.time.Duration 类代表时间大小,以下场景适用:
示例:
@ConfigurationProperties("app.system")
public class AppSystemProperties {
@DurationUnit(ChronoUnit.SECONDS)
private Duration sessionTimeout = Duration.ofSeconds(30);
private Duration readTimeout = Duration.ofMillis(1000);
public Duration getSessionTimeout() {
return this.sessionTimeout;
}
public void setSessionTimeout(Duration sessionTimeout) {
this.sessionTimeout = sessionTimeout;
}
public Duration getReadTimeout() {
return this.readTimeout;
}
public void setReadTimeout(Duration readTimeout) {
this.readTimeout = readTimeout;
}
}
Spring 使用 DataSize 类代表数据大小,以下场景适用:
示例:
@ConfigurationProperties("app.io")
public class AppIoProperties {
@DataSizeUnit(DataUnit.MEGABYTES)
private DataSize bufferSize = DataSize.ofMegabytes(2);
private DataSize sizeThreshold = DataSize.ofBytes(512);
public DataSize getBufferSize() {
return this.bufferSize;
}
public void setBufferSize(DataSize bufferSize) {
this.bufferSize = bufferSize;
}
public DataSize getSizeThreshold() {
return this.sizeThreshold;
}
public void setSizeThreshold(DataSize sizeThreshold) {
this.sizeThreshold = sizeThreshold;
}
}
@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {
@NotNull
private InetAddress remoteAddress;
@Valid
private final Security security = new Security();
// ... getters and setters
public static class Security {
@NotEmpty
public String username;
// ... getters and setters
}
}
你也可以自定义一个名为 configurationPropertiesValidator 的校验器 Bean。获取这个 @Bean 的方法必须声明为 static。