认识YAML和Propertis

395 阅读8分钟

认识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.propertiesapplication.ymlapplication.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应用程序在启动时会遵循下面的顺序进行加载配置文件:

  1. 类路径下的配置文件
  2. 类路径内config子目录的配置文件
  3. 当前项目根目录下的配置文件
  4. 当前项目根目录下config子目录的配置文件

示例项目配置文件存放结构如下所示:

. project-sample
├── config
│   ├── application.yml4)
│   └── src/main/resources
|   │   ├── application.yml1)
|   │   └── config
|   |   │   ├── application.yml2)
├── application.yml3

启动时加载配置文件顺序:1 > 2 > 3 > 4

src/main/resources下的配置文件在项目编译时,会放在target/classes下。

优先级覆盖

SpringBoot配置文件存在一个特性,优先级较高的配置加载顺序比较靠后相同名称的配置优先级较高的会覆盖优先级较低的内容。

为了更好地解释这一点,我们根据对应的加载顺序分别创建一个application.yml配置文件,来验证根据优先级的不同是否存在覆盖问题,如下图所示:

image-20231222231754339

在上面四个配置文件中都有一个名为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/configclasses/config两个目录的配置文件,是否按照优先级进行覆盖呢?

删除另外两个,只保留project/configclasses/config两个位置的配置文件,启动项目控制台输出如下所示:

配置名称:project/config

同样是输出了优先级最高的project/config配置文件的内容,覆盖顺序为:4 > 1

测试点:单顺序加载

平时在项目开发中一般都是将application.yml配置文件放在src/main/resources目录下,然而根据上面的加载顺序来看,我们可以将配置文件放置在任意一处,启动时都会进行加载。

仅保留classes/config位置的配置文件,启动项目控制台输出内容如下所示:

配置名称:classes/config

IDEASpringBoot的支持真的很强大, 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 发布!