认识YAML和Propertis
1.前言☕
大家好,我是Leo哥🫣🫣🫣,今天给大家带来关于精品SpringBoot专栏,暂且就给他起名为循序渐进学SpringBoot,这里我参考了我上一个专栏:循序渐进学SpringSecurity6。有需要的朋友可以抓紧学习来哈,带你从SpringSecurity从零到实战项目。好了,我们进入正题,为什么会有SpringBoot这个专栏呢,是这样的,今年Leo哥也是正在重塑知识体系,从基础到框架,而SpringBoot又是我们框架中的核心,我觉得很有必要通过以博客的形式将我的知识系列进行输出,同时也锻炼一下自己的写作能力,如果能帮到大家那就更好啦!!!本地系列教程会从SpringBoot基础讲起,会以知识点+实例+项目的学习模式由浅入深对Spring Boot框架进行学习&使用。好了,话不多说让我们开始吧😎😎😎。
2.概述
在Spring Boot中,配置文件是一个核心组件,它允许开发者轻松管理和调整应用程序的行为。最常见的配置文件格式是YAML(YAML Ain't Markup Language)和 Properties。本文将深入探讨这两种格式在SpringBoot中的使用和它们的区别。
在Spring Boot中,application.properties和application.yml或application.yaml是两种主要的配置文件格式。这些文件通常位于src/main/resources目录下。
2.1 Properties格式
-
格式: Properties文件是键值对格式,使用等号(
=)分隔键和值。 -
示例
propertiesCopy codeserver.port=8081 myapp.name=My SpringBoot App
2.3 yml文件基本认识
Key-Value形式的格式,有层次性比较直观,配置参数简单明了。可用于当做SpringBoot的配置文件。
对于要配置的参数需要知道对应的Key,以及这个Key所在的层级范围。
1. 语法约束
- k: v 表示键值对关系,冒号后面必须有一个空格。
- 使用空格的缩进表示层级关系,空格数目不重要,只要是左对齐的一列数据,都是同一个层级的。
- 大小写敏感。
- 缩进时不允许使用Tab键,只允许使用空格。
- 松散表示,Java中对于驼峰命名法,可用原名或使用-代替驼峰,如Java中的lastName属性,在yml中使用lastName或last-name都可正确映射。
2. 基础使用
ps:关于Value使用双引号、单引号、不使用任何引号。
1、字符串默认不用加上单引号或者双绰号; 2、 " ": 双引号: 不会转义字符串里面的特殊字符; 特殊字符会作为本身想表示的意思。 name: “zhangsan \n lisi”:输出;zhangsan 换行 lisi 3、 ’ ':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据。即使用单引号里面的都会当做字符串内容原样显示。
2.3 YAML格式
-
格式: YAML是一种更为人性化的数据序列化格式,使用缩进来表示层级关系。
-
示例
server: port: 8081 myapp: name: My SpringBoot App
2. 使用差异
2.1 可读性与编写
- YAML: 易于阅读和编写,尤其是对于复杂或嵌套的数据结构。它支持列表和字典这样的数据结构,使得配置更加直观。
- Properties: 更加简单和传统,但在表示复杂或分层的数据时可能不够直观。
个人还是比较YAML的文件格式,因为看起来真的比较简介明了。
2.2 数据类型
- YAML: 自动识别数据类型,如布尔值、整数、浮点数等。
- Properties: 默认将所有值视为字符串,需要在应用中显式转换数据类型。
2.3 加载顺序
在Spring Boot中,如果同时存在YAML和Properties文件,Spring Boot会先加载application.properties,然后加载application.yml,其中后者的配置将覆盖前者。
3. 配置绑定
在SpringBoot中,无论是使用YAML还是Properties,都可以轻松地将配置绑定到Java对象上。使用@Value注解或@ConfigurationProperties注解可以实现这一点。
3.1 使用@Value
@Component
public class MyAppConfig {
@Value("${myapp.name}")
private String name;
}
此处不推荐使用@Value方式注入属性,原因有二:
- 对于较为复杂的数据结构难以设置,诸如
Map,Object; - 不支持对属性值进行校验,诸如
@Length,@Size等.
3.2 使用@ConfigurationProperties
mail:
host: mailer@mail.com
port: 9000
from: mailer@mail.com
@Getter
@Setter
@Configuration
//@PropertySource("classpath:configprops.properties")
@ConfigurationProperties(prefix = "mail")
@Validated
public class ConfigProperties {
@Validated
@Getter
@Setter
public static class Credentials {
@Length(max = 4, min = 1)
private String authMethod;
private String username;
private String password;
}
@NotBlank
private String host;
@Min(1025)
@Max(65536)
private int port;
@Pattern(regexp = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6}$")
private String from;
private Credentials credentials;
private List<String> defaultRecipients;
private Map<String, String> additionalHeaders;
}
上述代码为获取Yaml配置文件中的属性值类,并且使用Configuration将类作为Bean提供给程序使用(可以去除此注解,将属性类型通过@Autowired注解注入Bean中).
注意,此处使用@ConfigurationProperties注解,获取前缀为mail的属性值.
Tips:
- 可以添加注解,对属性值进行校验,诸如
@NotBlank,@Pattern等; - 通过
public static class Credentials类,将属性值注入Object对象内; - 通过
@PropertySource注解实现从指定的配置文件读取属性设置.
4.属性优先级
SpringBoot应用程序在启动时会遵循下面的顺序进行加载配置文件:
- 类路径下的配置文件
- 类路径内config子目录的配置文件
- 当前项目根目录下的配置文件
- 当前项目根目录下config子目录的配置文件
示例项目配置文件存放结构如下所示:
. project-sample
├── config
│ ├── application.yml (4)
│ └── src/main/resources
| │ ├── application.yml (1)
| │ └── config
| | │ ├── application.yml (2)
├── application.yml (3)
启动时加载配置文件顺序:1 > 2 > 3 > 4
src/main/resources下的配置文件在项目编译时,会放在target/classes下。
优先级覆盖
SpringBoot配置文件存在一个特性,优先级较高的配置加载顺序比较靠后,相同名称的配置优先级较高的会覆盖掉优先级较低的内容。
为了更好地解释这一点,我们根据对应的加载顺序分别创建一个application.yml配置文件,来验证根据优先级的不同是否存在覆盖问题,如下图所示:
在上面四个配置文件中都有一个名为name的配置,而红色字体标注的内容就是每个配置文件name的配置内容,下面我们来启动项目测试下输出内容。
运行测试
在测试之前我们让启动类实现CommandLineRunner接口,如下所示:
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Environment environment = context.getBean(Environment.class);
System.out.println("访问链接:http://localhost:" + environment.getProperty("server.port"));
System.out.println("(♥◠‿◠)ノ゙ 项目启动成功 ლ(´ڡ`ლ)゙ \n");
}
@Value("${name}")
private String name;
@Override
public void run(String... args) throws Exception {
System.out.println("配置名称:" + name);
}
}
测试一:顺序覆盖
保留上面四个对应加载顺序的配置文件,启动项目,控制台输出内容:
配置名称:project/config
期望与实际输出是符合的,项目根下的config目录是最后加载的,所以它的优先级相对其他三个来说是最高的,覆盖顺序为:4 > 3 > 2 > 1。
测试二:跨顺序覆盖
上一个测试点我们对每一个加载顺序都对应添加了一个配置文件,那如果我们只有两个project/config、classes/config两个目录的配置文件,是否按照优先级进行覆盖呢?
删除另外两个,只保留project/config、classes/config两个位置的配置文件,启动项目控制台输出如下所示:
配置名称:project/config
同样是输出了优先级最高的project/config配置文件的内容,覆盖顺序为:4 > 1
测试点:单顺序加载
平时在项目开发中一般都是将application.yml配置文件放在src/main/resources目录下,然而根据上面的加载顺序来看,我们可以将配置文件放置在任意一处,启动时都会进行加载。
仅保留classes/config位置的配置文件,启动项目控制台输出内容如下所示:
配置名称:classes/config
IDEA对SpringBoot的支持真的很强大, classes/config下的配置文件同样提供了关键字提醒功能。
了解配置文件的加载顺序,才能得心应手的进行配置覆盖,完全控制在不同环境下使用不同的配置内容,要记住classes/application.yml优先级最低,project/config/application.yml优先级最高。
4.选择使用哪一种
选择使用YAML还是Properties主要取决于个人偏好和项目需求。如果配置相对简单,或者团队更习惯于Properties,那么使用Properties是合适的。相反,如果配置结构复杂或者需要更好的可读性,YAML可能是更好的选择。
5.小结
Spring Boot通过支持YAML和Properties两种配置文件格式,为开发者提供了灵活性和选择。理解这两种格式的特点和使用场景,可以帮助开发者更好地管理和维护Spring Boot应用程序的配置。
以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。
如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步至公众号。
本文由博客一文多发平台 OpenWrite 发布!