springboot通过可外部化的配置能够让相同的代码运行在不同的条件下,使得代码的稳定性、适配性更强,特别是为以docker镜像发布的程序提供了更为方便的操作。
可以通过属性文件(.properties)、yml文件、环境变量、命令行参数等多种方式来传递配置属性。如果有微服务配置中心配合就更为优良。属性值、环境变量可以通过@Value直接注入到Bean中,结构化的属性值可以通过@ConfigurationProperties注入。
属性赋值优先级
springboot采用了属性源优先策略,优先级高的属性值会覆盖优先级低的。属性优先级按照如下顺序排列:
- 如果devtools启动,则读取devtools属性文件(~/.spring-boot-devtools.properties)。
- 如果在单元测试主类注解了@TestPropertySource,则在单元测试过程优先读取这里指的的配置文件。
- 命令行参数。
- 环境变量SPRING_APPLICATION_JSON中的属性值。
- ServletConfig初始化参数。
- ServletContext 初始化参数。
- 来自java:comp/env的JNDI 属性。
- Java系统属性,即可以通过System.getProperties()获取的属性。
- OS环境变量
- 通过random.*.文件定义的随机属性值。
- jar之外的特定环境属性文件 (application- {profile}.properties and YAML variants)。
- jar包内部的特定换属性文件 (application- {profile}.properties and YAML variants)。
- jar包外部通用属性文件(application.properties and YAML variants)。
- jar包内部通用属性文件(application.properties and YAML variants)。
- 通过@PropertySource注解指定的@Configuration配置文件。
- 主类中通过SpringApplication.setDefaultProperties设置的属性。
举例说明
下面通过一个实际的例子具体说明一下。
import org.springframework.stereotype.*;
import org.springframework.beans.factory.annotation.*;
@Component
public class MyBean {
@Value("${name}")
private String name;
}
name属性值可以通过下面几个途径提供:
- resources下的application.properties、jar包之外的指定环境的application-dev.properties,命令行:
java -jar app.jar --name="dev"
- spring.application.json,命令行:
java -jar myapp.jar --spring.application.json='{"name":"test"}'
随机数属性配置
springboot支持使用随机类配置属性值的方法,这样可以在一些加密或者测试环节简化数据制作成本。
在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]}
程序每次启动都会按照这些方法产生一个随机值。
命令行属性
springboot通过命令行方式设置的属性值会覆盖掉其他方式的属性值,通过--来引用。
java -jar app.jar --spring.port=8008
效果等同于在application.properties中配置
spring.port=8008
如果要程序忽略命令行属性,则在主程序启动类里边使用
SpringApplication.setAddCommandLineProperties(false)
属性文件配置
springboot可以很灵活的配置属性文件,但是建议按照缺省的约定去使用配置文件,即放置到resources目录下的application.properties,微服务情况下放置到配置中心,过度灵活就带来了不规范,反而降低了系统的可维护性。
属性中的占位符
属性值可以使用前面定义的属性名称引用的方式来直接将该属性对应的值插入到此处,从而象使用变量一样配置属性文件。
app.name=MyApp
app.description=${app.name} is a Spring Boot application
这个配置等同于
app.name=MyApp
app.description=MyApp is a Spring Boot application
YAML格式替换properties格式配置文件
YAML格式比properties格式更为简洁,推荐使用该格式来编写配置文件。
- list类型属性配置格式
my:
servers:
- dev.example.com
- another.example.com
等价于
my.servers[0]=dev.example.com
my.servers[1]=another.example.com
- 多环境YAML配置文件
多个profile的配置文件可以使用命名约定的方式分多个配置文件实现,也可以将不同环境的配置放到一个配置文件中,使用---分割。
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120