spring boot 属性配置文件
可扩展的配置
Spring 可以使用外部配置, 这样的话同一个包就可以在不同的运行环境, 使用不同的配置了, 同时也可以保护生产环境配置。
外部配置支持的呈现方式:
properties文件YAML文件环境变量命令行参数
获取属性值的方法:
@Value: 通过@Value注解,注入到字段里Environment: 通过Environment抽象类访问@ConfigurationProperties: 通过@ConfigurationProperties注解绑定的类上
spring 获取属性值的顺序:
当
devtools活动时 ,使用devtools在在$HOME/.config/spring-boot文件中的全局设置测试类上
@TestPropertySource注解指定的配置测试类上的
properties属性,使用@SpringBootTest注解时可用.命令行参数
SPRING_APPLICATION_JSON里配置的属性值,SPRING_APPLICATION_JSON是一个环境变量或者系统属性。使用方法如下:作为环境变量:
1
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar
或者作为系统属性:
1
$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar
或者作为spring 命令行参数:
1
$ java -jar myapp.jar --spring.application.json='{"name":"test"}'
ServletConfig初始化参数ServletContext初始参数JNDI from
java:comp/envJava 系统属性
System.getProperties()操作系统环境变量
RandomValuePropertySourceJar包外,带有指定
profile的application proerties文件(application-{profile}.properties),YAML也可以Jar包里,带有指定
profile的application proerties文件(application-{profile}.properties)YAML也可以Jar包外的
application.properties文件(YAML也可以, 如果properites和yml文件同时存在,什么使用properties)Jar包里的
application.properties文件(YAML也可以, 如果properites和yml文件同时存在,什么使用properties)配置类上的
@PropertySource指定的配置。注意: 这样指定的配置,在Spring上下文件刷新之前是不会添加到Environment里的, 所以对于某些配置来说有就迟了,如logging.*andspring.main.*,它们是在刷新之前就要被读取SpringApplication.setDefaultProperties指定的默认配置
假设我们有如下组件:
1 | import org.springframework.stereotype.*; |
在应用的classpath 里(比如Jar包里)有一个application.properties提供了name属性的值。 当要在测试环境运行的时候, 可以在jar包外放一个application.properties,可以覆盖name属性的值。 对于一次性的配置, 可以用命令行参数设置:java -jar app.jar --name="Spring"
Spring Boot 加载配置文件的时候支持通配符,默认是Jar外config/*/目录下的application.properties文件都能加载到。指定spring.config.additional-location 和 spring.config.location 属性的时候也支持通配符。
如果通配符匹配到的目录有多个, 那么每个目录下的application.properties都会被加载处理,比如有两个配置文件/config/redis/application.properties 和 /config/mysql/application.properties,把加载路径配置为config/*/,那么这两个文件里的属性都能被加载到。
注意: 如果匹配目录的话,只能有一个*号并且要以/结尾,匹配文件的话格式为*/<filename>
配置随机值
RandomValuePropertySource 可以产生integer, long, uuids, string 类型的随机值
1 | my.secret=${random.value} |
访问命令行参数
Spring boot 会把命令行可选参数(以--开头的参数),转换为property并添加到Environment中, 而且命令行参数里的属性在比其它来源加载的属性优先级都高。
如果不想命令行参数加入Environment,可以使用SpringApplication.setAddCommandLineProperties(false)来禁用。
Applicatin 属性配置文件 application.proerties
application.properties 是spring boot的默认配置文件, spring会从以下位置去加载(已按优先级排序):
- 当前目录的
/config子目录 - 当前目录
- classpath的
/config子包 - classpath目录下
当然, 配置文件名是可以改的,通过修改spring.config.name属性, 路径也可以改,通过修改spring.config.location属性。
注意: 这两上属性非常早就要被spring用到, 才能决定去哪里加载配置文件。 所以一般是要设置为系统环境变量、或者系统属性、或者命令行参数。 spring.config.location 值只能是目录, 可以多个目录以逗号,分隔,不支持profile
todo
指定profile的属性
有些属性是和运行环境相关的, 我们希望在不同步运行环境使用不同一属性, 这时候就可以用profie。 和profile 相关的配置文件全名约定为:application-{profile}.properties。 在Spring Environment 中, profile是可以指定多个的, 是个数组, 默认值是[default].
注意: application.properties 和 application-{profile}.properties 是叠加关系, 不是互斥关系 。 spring 先加载application.properties, 然后再加载当前激活的profile, 如果有相同步属性值就用 profile里面的覆盖application.properties里面的。 如果指定了多个profile, 也是按顺序加载,最多属性是多个profile的并集, 对于相同的属性, 后面的覆盖前面的。
注意: 如果spring.config.location 属性里面指定了具体文件名, 那这些文件是不能使用对应的profile的。如果想使用profile, spring.config.location属性只能使用目录
我们有3个配置文件, application.properties ,还有两个profile: test 和test2
1 | $ tree config/ |
内容分别是
1 | application.properties |
建了个java类,访问localhost:8080的时候,程序会介绍自己的运行环境
1 | @RestController |
当使用test、test2两个profile的时候
1 | $ java -jar myproject-0.0.1-SNAPSHOT.jar --spring.profiles.active=test,test2 |
结果为:
1 | $ curl localhost:8080 |
可以看到指定了profile的时候, 只存在于application.properties中的my.name属性成功加载到了。 而application-test.properties中的my.env 覆盖了application.properties中的。而test2中的my.profile覆盖了test中的。
总结
application.properties和profile之间是并集关系,对于相同的属性,profile覆盖application.properties。profile之间也是求并集,对相同部分, 按指定顺序,后面的覆盖前面的。