前言
本博文主要记录SpringBoot有关配置文件的一些知识,包括配置文件的优先级、配置规则、文件位置等等规范。作为笔者学习之路上的记录。
全局配置文件以及优先级概述
全局配置文件优先级概述
SpringBoot默认使用一个名字叫做application.properties或者application.yaml(也可以是.yml)的文件作为全局配置文件。我们使用脚手架创建的标准的SpringBoot的项目,配置文件会自动生成在classpath下面。根据官网介绍,SpringBoot在启动过程中加载配置文件会从以下四个位置依次查找配置文件:
- 项目根目录下的config文件夹下的配置文件
- 项目根目录下的配置文件
- 项目classpath下的config文件夹下的配置文件
- 项目classpath下的配置文件
看到这里,我们可能会有疑问。项目根路径是啥意思呀?简单点来说,就是项目的部署路径。我们在开发的时候,就是项目根目录,如下图所示:

但在我们项目部署的时候,需要注意的一点是:我们的jar包所在的路径就是项目跟目录。举个例子来讲:如果我们的项目jar部署在服务器的/rubin/project/下面,项目的根路径就是/rubin/project/。如果是war包部署的话,个人推测是Web服务器项目发布地址的根路径,有兴趣的小伙伴可以自己尝试一下。
配置文件的互补特性
所谓配置文件的互补特性,也就是说高优先级的配置文件属性与低优先级配置文件的属性如果不冲突的话,则会共同存在。但是如果配置文件之间的配置属性发生了冲突,则会以高优先级配置文件的配置属性为准。
版本间对于文件后缀的优先级
由于SpringBoot的版本之间对于application.properties和application.yaml的优先级不一致,所以在项目开发前一定要注意当前版本对于后缀文件的优先级。推荐项目中配置文件的后缀做统一处理。
SpringBoot2.4.0之前的版本,优先级properties > yaml。 SpringBoot2.4.0 版本的优先级则是 yaml > properties。我们也可以配置如下属性,来强制指定 优先级properties > yaml :
spring.config.use-legacy-processing = true
外部配置文件指定
除了上文阐述的配置文件的位置之外,我们还可以指定外部的配置文件来作为全局配置文件。指定方法便是在我们项目的启动脚本中添加配置文件位置的参数,示例命令如下所示:
java -jar myproject.jar --spring.config.location=/rubin/config/myproject.properties
也可以通过以下命令指定配置文件的名称(即不叫application**,但是配置文件要在上述四个地方中的一个):
java -jar myproject.jar --spring.config.name=myproject
配置属性的注入使用
自定义配置属性的识别
为什么作为本章节第一个小节?是因为本小节主要介绍让SpringBoot识别我们自定义属性,配制好之后,我们在书写配置的时候会自动给出提示。
首先,我们需要在项目中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
添加好之后,在下文我们写完配置类之后,重新运行项目或者使用“CTRL + F9”(即Build Project)则可以自动生成属性配置识别文件。
配置属性注入实体
我们可以将一组前缀相同的配置封装进一个实体中来维护。假如我们有如下一组属性:
persion.id=1
persion.name=Tom
persion.hobby=吃饭,睡觉,打豆豆
persion.family=father,mother
persion.map.k1=v1
persion.map.k2=v2
persion.pet.type=dog
persion.pet.name=旺财
我们就需要创建以下实体类来做属性映射:
@Data
public class Pet {
private String type;
private String name;
}
@Data
@Component
@ConfigurationProperties(prefix="persion")
public class Persion {
private String name;
private List hobby;
private String[] family;
private Map map;
private Pet pet;
}
或者
@Data
@Configuration
@ConfigurationProperties(prefix="persion")
public class Persion {
private String name;
private List hobby;
private String[] family;
private Map map;
private Pet pet;
}
其中,@ConfigurationProperties(prefix = "person")注解的作用是将配置文件中以person开头的属性值通过setXX()方法注入到实体类对应属性中。@Component注解的作用是将当前注入属性值的Person类对象作为Bean组件放到Spring容器中,只有这样才能被@ConfigurationProperties注解进行赋值。
除此之外,我们还可以在@Bean上注入属性,示例如下:
组件类:
@Data
public class AnotherComponent {
private boolean enabled;
private InetAddress remoteAddress;
}
配置类:
@Configuration
public class MyService {
@ConfigurationProperties("another")
@Bean
public AnotherComponent anotherComponent(){
return new AnotherComponent();
}
}
配置文件:
another.enabled=true
another.remoteAddress=192.168.10.11
YAML配置文件对应的数据类型配置
本小节,我们介绍一下YAML配置文件针对不同数据类型的属性值的配置方案。
普通数据类型
当YAML配置文件中配置的属性值为普通数据类型时,可以直接配置对应的属性值,同时对于字符
串类型的属性值,不需要额外添加引号,示例代码如下:
server:
port: 8080
servlet:
context-path: /hello
数组和单列集合类型
当YAML配置文件中配置的属性值为数组或单列集合类型时,主要有两种书写方式:缩进式写法和行内式写法。
其中,缩进式写法还有两种表示形式,示例代码如下:
person:
hobby:
- play
- read
- sleep
或者使用如下示例形式:
person:
hobby:
play,
read,
sleep
行内式写法如下:
person:
hobby: [play,read,sleep]
通过上述示例对比发现,YAML配置文件的行内式写法更加简明、方便。另外,包含属性值的中括号“[]”还可以进一步省略,在进行属性赋值时,程序会自动匹配和校对。
Map集合和对象类型
当YAML配置文件中配置的属性值为Map集合或对象类型时,YAML配置文件格式同样可以分为两种书写方式:缩进式写法和行内式写法。
其中,缩进式写法的示例代码如下:
person:
map:
k1: v1
k2: v2
对应的行内式写法示例代码如下:
person:
map: {k1: v1,k2: v2}
配置属性注入字段
配置属性注入字段很简单,在字段上面标注@Value注解即可。示例如下:
配置类:
@Configuration
public class JdbcConfiguration {
@Value("${jdbc.url:jdbc:mysql://127.0.0.1:3306/springboot_h}")
String url;
@Value("${jdbc.driverClassName:com.mysql.jdbc.Driver}")
String driverClassName;
@Value("${jdbc.username:root}")
String username;
@Value("${jdbc.password:root}")
String password;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
配置文件如下:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/springboot_h
jdbc.username=root
jdbc.password=123
注意:冒号后面是默认值,是可选项(即可以设置也可以不设置)。
配置属性的松散绑定
所谓的松散绑定,就是我们的配置文件没有必要严格按照我们配置类的字段名称来配制,可以有一些格式上的变化。
举个例子来将,比方我们定义的配置Bean如下所示:
@Data
@Component
@ConfigurationProperties("acme.my-person.person")
public class OwnerProperties {
private String firstName;
}
我们可以配置成以下格式:
acme:
my-person:
person:
first-name: 泰森
我们可以看到,框架会按照一定的规则来匹配两者。匹配规则总结如下:
属性文件中配置 | 说明 |
acme.my-project.person.first-name | 羊肉串模式case, 推荐使用 |
acme.myProject.person.firstName | 标准驼峰模式 |
acme.my_project.person.first_name | 下划线模式 |
ACME_MYPROJECT_PERSON_FIRSTNAME | 大写下划线,如果使用系统环境时候推荐使用 |
@ConfigurationProperties vs @Value
我们两种配置方式对于松散绑定的支持程度还是不同的,我们总结如下:
特征 | @ConfigurationProperties | @Value |
宽松的绑定 | yes | limited(详见下方官网截图) |
元数据支持 | yes | no |
SpEL 表达式 | no | yes |
应用场景 | 批量属性绑定 | 单个属性绑定 |
对于@Value注解的松散绑定,官网原文如下:

翻译一下大致的意思就是,如果我们在@Value注解中配置成羊肉串模式,系统会绑定配置文件中的羊肉串模式、驼峰命名法或者全大写下划线格式的系统变量到该属性上。但是配置成其他格式则只能严格按照其他格式的命名规范去匹配才行。
文章评论