SpringBoot
允许你外置化项目的配置信息,你可以使用properties
文件、YAML
文件、环境变量、命令行参数来设置配置信息。
1 优先级
SpringBoot
提供多种外部配置方式,这些方式的优先级如下(由高到低):
- 命令行参数
- 来自
java:comp/env
的JNDI
属性 - Java系统属性(
System.getProperties()
) - 操作系统环境变量
RandomValuePropertySource
配置的random.*
属性值jar
包外部的application-{profile}.properties
或application.yml
(带spring.profile
)配置文件jar
包内部的application-{profile}.properties
或application.yml
(带spring.profile
)配置文件jar
包外部的application.properties
或application.yml
(不带spring.profile
)配置文件jar
包内部的application.properties
或application.yml
(不带spring.profile
)配置文件@Configuration
注解类上的@PropertySource
- 通过
SpringApplication.setDefaultProperties
指定的默认属性
2 使用
2.1 自定义配置
例如,在项目中定义一个类MyBean
,它的一个成员变量name
的值需要从外部配置文件中读取,可以使用@Value
注释:
@Component("myBean")
public class MyBean {
@Value("${MyBean.name}")
private String name;
}
${MyBean.name}
表示获取变量MyBean.name
的值,该变量可以在application.properties
文件中定义:
MyBean.name=MyBean-HaHa
2.2 使用SpringBoot提供的随机值
SpringBoot
内置了一个RandomValuePropertySource
类,提供了生成随机值的功能。我们可以在配置文件中或者代码中直接通过random.*
获取SpringBoot
提供的随机值。
random.value
—— 返回一个随机字符串random.int
—— 返回一个随机int
类型值random.long
—— 返回一个随机long
类型值random.uuid
—— 返回一个随机的uuid
random.int(10)
—— 返回一个小于10
的int
类型值random.int[1024, 65536]
—— 返回一个范围类的int
类型值
可以在application.properties
配置文件中获取并赋值给自定义的变量:
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]}
也可以直接在程序中取值:
@Component("myRandom")
public class MyRandom {
@Value("${random.value}")
//@Value("${my.secret}")
private String secret;
@Value("${random.int}")
//@Value("${my.number}")
private Integer number;
@Value("${random.long}")
//@Value("${my.bignumber}")
private Long bigNumber;
@Value("${random.uuid}")
//@Value("${my.uuid}")
private String uuid;
@Value("${random.int(10)}")
//@Value("${my.number.less.than.ten}")
private Integer numberLessThanTen;
@Value("${random.int[1024,65536]}")
//@Value("${my.number.in.range}")
private Integer numberInRange;
@Override
public String toString() {
return "MyRandom{" +
"secret='" + secret + '\'' +
", number=" + number +
", bigNumber=" + bigNumber +
", uuid='" + uuid + '\'' +
", numberLessThanTen=" + numberLessThanTen +
", numberInRange=" + numberInRange +
'}';
}
}
2.3 访问命令行属性
命令行属性通过java -jar app.jar --name="String" --serverPort=8888
来传递。
参数的传递格式为--xxx=XXX
。
参数名可以使自定义的,也可以是SpringBoot
内置的参数名。
如果想禁用命令行传递属性功能,可以使用SpringApplication.setAddCommandLineProperties(false)
进行配置。
2.4 使用应用程序的.properties属性文件
2.4.1 优先级顺序
SpringApplication
从以下位置中加载application.properties
文件到Spring
的环境中:
-
当前目录的
/config
子目录 -
当前目录
-
classpath
下的/config
目录 -
classpath
目录
说明:
(1)1和2中所描述的“当前目录”是指项目打包之后
.jar
或.war
包所在的目录,适合生产环境。(2)3和4是项目中的目录,通常就是指
web
项目中的src/main/resources/config
目录或src/main/resources
目录,适合开发环境。(3)如果4个地方都有配置文件,那么配置生效的优先级从
1
到4
,搜索配置文件的顺序从4
到1
,后加载的会覆盖先加载的。(4)使用配置文件之后,
SpringBoot
启动时,会自动把配置信息读取Spring
容器中,并覆盖SpringBoot
的默认配置。(5)可以使用
YAML
(.yml
)文件替换.properties
文件,效果相同。
2.4.2 自定义文件名
如果不喜欢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
注意:
spring.config.name
和spring.config.location
被加载的时期非常靠前,因此必须将它们定义为环境属性(通常是OS环境变量,系统属性或命令行参数)。
配置文件生效的优先级顺序如下:
file:./config/
file:./
classpath:/config/
classpath:/
如果通过spring.config.location
配置了配置文件的位置,那么将会替换1
到4
中的值。例如--spring.config.location = classpath:/custom-config/,file:./custom-config/
,则1
到4
变为:
file:./custom-config/
classpath:/custom-config/
或者,当使用spring.config.additional-location
环境变量来配置自定义位置时,默认的4个配置位置继续保留,并且自定义位置的优先级高于默认位置。例如--spring.config.additional-location = classpath:/custom-config/,file:./custom-config/
,则优先级如下:
file:./custom-config/
classpath:/custom-config/
file:./config/
file:./
classpath:/config/
classpath:/
2.4.3 定义特定于配置文件的属性
除了application.properties
文件之外,还可以通过约定的命名规则来指定特定环境下的配置文件:application-{profile}.properties
。
如果没有指定,默认情况下SpringBoot
会加载一个名为application-default.properties
的文件。
定义的特定环境的配置文件的优先级最高,无论它的位置在哪里。
需要在application.properties
文件中通过spring.profiles.active
来具体激活一个或多个配置文件,也可以通过spring.profiles.include
来使多个配置文件同时生效。
2.5 获取(使用)属性值
2.5.1 使用@Value("${xxx}")
最简单的方式就是通过@Value
注解注入属性值。
2.5.2 使用@ConfigurationProperties
SpringBoot
可以方便的将属性注入到一个配置对象中。例如:
my.name=Isea533
my.port=8080
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
配置对象:
@ConfigurationProperties(prefix="my")
public class Config {
private String name;
private Integer port;
private List<String> servers = new ArrayList<String>();
public String geName(){
return this.name;
}
public Integer gePort(){
return this.port;
}
public List<String> getServers() {
return this.servers;
}
}
SpringBoot
会自动将prefix="my"
前缀为my
的属性注入进来。
SpringBoot
会自动转换类型,当使用List
的时候需要注意在配置中对List
进行初始化!
SpringBoot
还支持嵌套属性注入,例如:
name=isea533
jdbc.username=root
jdbc.password=root
对应的配置类:
@ConfigurationProperties
public class Config {
private String name;
private Jdbc jdbc;
public Integer gePort(){
return this.port;
}
public Jdbc getJdbc() {
return this.jdbc;
}
}
class Jdbc {
private String username;
private String password;
// getter...
}
jdbc
开头的属性都会注入到Jdbc
对象中。
在@Bean
方法上使用@ConfigurationProperties
,SpringBoot
会将属性注入到返回的对象里面:
@ConfigurationProperties(prefix = "foo")
@Bean
public FooConfig fooConfig() {
...
}
2.5.3 属性占位符
SpringBoot
在配置文件中还支持属性占位符:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
可以在配置文件中引用前面配置过的属性。
通过形如${app.name:默认名称}
方式还可以设置默认值,当找不到引用的属性时,会使用默认值。
2.5.4 属性名匹配规则
例如有如下配置对象:
@Component
@ConfigurationProperties(prefix="person")
public class ConnectionSettings {
private String firstName;
}
firstName
可以使用的属性名如下:
person.firstName
,标准的驼峰式命名。person.first-name
,虚线(-
)分割方式,推荐在.properties
和.yml
配置文件中使用。PERSON_FIRST_NAME
,大写下划线形式,建议在系统环境变量中使用。
2.5.5 属性验证
可以使用JSR-303
注解进行验证,例如:
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
@NotNull
private InetAddress remoteAddress;
// getters and setters ...
}