这里将介绍 spting boot
的配置文件、多配置、自定义配置等。
参考资料
- Spring Boot2 系列教程(四)理解配置文件 application.properties
- spring Boot 2.x | 配置文件,自定义配置,多环境配置
- Springboot2.x——读取自定义配置文件
- SpringBoot2.x基础篇:配置文件的加载顺序以及优先级覆盖
文件格式
在 Spring Boot
中,配置文件有两种不同的格式,一个是 properties
,另一个是 yaml
。
虽然 properties
文件比较常见,但是相对于 properties
而言,yaml
更加简洁明了,而且使用的场景也更多,很多开源项目都是使用 yaml
进行配置(例如 Hexo
)。除了简洁,yaml
还有另外一个特点,就是 yaml
中的数据是有序的,properties
中的数据是无序的,在一些需要路径匹配的配置中,顺序就显得尤为重要(例如我们在 Spring Cloud Zuul
中的配置),此时我们一般采用 yaml
。
项目内可以同时存在 application.properties
、 application.yml
两个文件,经过测试发现, properties
优先级会高一些,相同名称的配置,会将 yml
内的配置覆盖掉。
文件顺序
spring boot
默认配置文件名为 application
,其默认可放置顺序为 4 个地方。
- 当前项目根目录下的
config
目录下 - 当前项目的根目录下
resources
目录下的config
目录下resources
目录下
按如上顺序,四个配置文件的优先级依次降低。如下:
所谓的优先级,就是优先级最高的会覆盖优先级低的,如上面,相同配置,以 当前项目根目录下的 config
目录下,即优先级为 1
的文件内容为主。
我们可以从 ConfigFileApplicationListener
这类便可看出,其中DEFAULT_SEARCH_LOCATIONS
属性设置了加载的目录:
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
自定义文件名
有的时候,我们并不想使用 application
作为配置文件名,或者,我们想把配置文件放到其他地方。
两个方法
- 指定名字
- 指定路径
指定配置文件
如果你的应用程序配置文件的名称不是 application
,你想要进行自定义,可以通过 --spring.config.name
命令行参数进行指定,如下所示:
java -jar project-sample.jar --spring.config.name=custome
注意事项:我们只需要指定配置文件的名称即可,可以使用 properties
或 yaml
文件格式,上面的配置会加载 src/main/resources/custome.yml
或 src/main/resources/custome.properties
。
通过 --spring.config.name
仅仅是修改了配置文件的名称,那如果是修改配置文件所处的目录位置,我们需要怎么做呢?
修改配置文件目录
SpringBoot
已经给我们准备好了,通过 --spring.config.location
参数就可以指定配置文件的位置,如下所示:
java -jar project-sample.jar --spring.config.location=classpath:/configs/custome.yml
如果一个配置文件无法满足你的需求,那你看看下面这个方式:
java -jar project-sample.jar --spring.config.location=classpath:/configs/custome.yml,classpath:/configs/default.properties
注意事项:支持通过命令行参数的方式指定多个配置文件,使用英文半角 , 隔开即可。
如果你通过 spring.config.location
指定的不是一个文件而是一个目录,在路径最后务必添加一个 /
结束,然后结合 spring.config.name
进行组合配置文件,组合示例如下:
加载/configs/application.properties 或/configs/application.yml(默认文件名)
java -jar project-sample.jar --spring.config.location=classpath:/configs/
加载/configs/custome.properties 或 /configs/custome.ymljava -jar project-sample.jar
--spring.config.location=classpath:/configs/ --spring.config.name=custome
注意事项: spring.config.name
该配置参数默认值为 application
,所以如果只是指定了 spring.config.location
并为目录形式,上面示例中会自动将 spring.config.name
追加到目录路径后,如果指定的 spring.config.location
并非是一个目录,这里会忽略 spring.config.name
的值。
ps: 这里还有两个问题需要回答。
- 指定路径之后,原来默认的文件还会加载吗?
指定文件之后,原来的默认文件不加载了。包括 yml
和 properties
文件,至于,指定路径后,依然想加载其他的配置文件,可以参考
- 如果指定多个加载文件,那么,优先级是怎么样的?
路径中,后面的配置文件优先级高。后面的会覆盖前面的。
还有在 IDEA
中,想要用不同的配置文件,图如下:
配置文件书写规则
这里只是我的经验,并没有进行系统考究。
这里主要有以下要素
- 大小写
- 顺序
- 系统变量
大小写问题
在 application.yml
写下如下内容
1 | logname: |
如果,我们要获取 logname.name
属性,获取的是 sss
。
如果,内容改为
1 | logname: |
那么,将会以全小写的 name
为主。
我在其他地方看到的
ps: SpringBoot
下此种写法不区分大小写,驼峰,-
,_
等书写形式都是兼容的。但是你的字母必须对应上啊,比如上面的user
你不能写成username
了。比如我这样写:datasource.u-r-l=xxx
也是能够被正常识别的~ 具体参照SpringBoot
的黑科技类:RelaxedNames
系统变量
1 | logname: |
文件读取顺序进阶
上面我们介绍了,4
个默认的配置文件,以及,自己可以自定义配置文件。但是,实际上,spring boot
默认加载的远不止那 4
个「可以发现那 4
个默认文件处于加载顺序的序号 17
」,有如下加载顺序:
数字越小优先级越高。
- 主目录中的
Devtools
全局设置属性(~/.spring-boot-devtools.properties
当devtools
处于活动状态时)。 @TestPropertySource
测试中的注释。@SpringBootTest#properties
测试中的注释属性。- 命令行参数。
- 来自
SPRING_APPLICATION_JSON
(嵌入在环境变量或系统属性中的内联JSON
)的属性。 ServletConfig
初始化参数。ServletContext
初始化参数。JNDI
属性来自java:comp/env
.Java
系统属性 (System.getProperties()
)。- 操作系统环境变量。
一RandomValuePropertySource
,只有在拥有性能random.*
。- 打包的
jar
(application-{profile}.properties
和YAML
变体)之外的特定于配置文件的应用程序属性。 - 打包在
jar
中的特定于配置文件的应用程序属性(application-{profile}.properties
和YAML
变体)。 - 打包
jar
之外的应用程序属性(application.properties
和YAML
变体)。 - 打包在
jar
中的应用程序属性(application.properties
和YAML
变体)。 @PropertySource
你的@Configuration
类的注释。- 默认属性(由
setting
指定SpringApplication.setDefaultProperties
)。
我们来举一个简单的例子,用来验证上面加载顺序的实现。
首先,在任一 application.yml
中添加如下内容。
1 | user: |
然后,创建一个 User
类。
1 | package com.jiezi.demo.entity; |
然后在随意弄一个 controller
1 | package com.jiezi.demo.test; |
当运行之后,返回的 Name
是你系统的名称,而不是 ccc
。
问题出在
@ConfigurationProperties(prefix = "user", ignoreUnknownFields = false)
这句话中。 当 prefix = "user"
的时候,由于系统文件优先级更高,这个时候就会被替换成环境变量。
在 macbook
中,你可以用 env
来查看你的环境变量。
想要解决也很简单。
只需要将 application.yml
中换成如下内容。
1 | person: |
然后,User
类换成
1 | package com.jiezi.demo.entity; |
配置读取
了解完配置文件之后,那我们的重点就放在了如何读取配置文件中的值了。
在这里,请参考如下文章。