SpringBoot学习笔记-06 yaml基础语法

        我们自动构建的SpringBoot初始项目,使用的配置文件是 application.properties ;但其实官方更推荐我们使用yaml,需要注意配置文件名必须是application.yaml,否则会无法读取(通过前面的学习,读者应该明白,这边之所以规定了读取的文件名,是在自动配置的相关规范中定义的默认值)。

1.配置文件语法格式对比

application.properties语法结构: key = value

server.port=8080

application.yaml语法结构: key:(空格)value

server:
  port: 8080 

以前的时候,还使用过xml配置:

<server>
    <port>8080<port>
</server>

2.yaml语法入门

A.yaml语法规范

1)大小写敏感

2)使用空格缩进表示层级所属关系

3)缩进只能用空格,不允许tab(类比py,py只能选择4个空格或者1个tab,不允许混用)

4)属于同一个层级的元素要求必须左对齐

a:
 bc:
  d:
#表示 a.bc.d

a:
 bc:
 d:
#表示 a.bc 和 a.d

5)用#表示注释

B.用yaml赋值

yaml的强大之处在于,可以直接为我们的实体类赋值。yaml支持的数据类型:键值对、数组、普通变量:

1.记住由于我们使用yaml配置文件,因此别忘了在pom.xml配置编译时包含

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <!--记住一定要配置SpringBoot主配置文件的过滤-->
                    <include>**/*.yaml</include>
                    <include>**/*.properties</include>
                    <include>**/*.txt</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>

2.Spring建议我们使用yaml注入值时,增加依赖以便提示是否有错

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

引入该依赖后,重启ideal,就会发现我们在用配置文件设置属性时,只要绑定了prefix,就会有提示:

[注]:这只是SpringBoot提供了便利性功能,与业务无关,因此打包的时候最好不要包含它,避免打包出的jar包内多出了一些不影响运行的jar包:

<build>
        <plugins>
            <!--SpringBoot打包-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
</build>

3.构建实体类进行实验

dogbean: &dogbean
  name: 小白 #单个不可再分的值:date、boolean、string、null(用~表示)、number等
  age: 4 #

personbean:
  name: zzt
  age: 22
  happy: true
  birth: 1999/4/14
  maps: {k1: v1,k2: v2} #键值对集合 map、set、hash、对象
  list: #数组 array、list、queue
    - code
    - music
  #多维数组简单值
  mulArr:
    -
      - zzt
      - zjm
    -
      - zjm
      - zzt
  #数组复杂对象
  dogs:
    -
      name: 小白
      age: 4
    -
      name: 小黑
      age: 5
  #值引用
  dog:
    <<: *dogbean

Dog.java

package com.zzt.vo;

public class Student {
    private Integer id;
    private String name;
    private Integer age;

    public Student() {
    }

    public Student(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 

Person.java

@Component
@ConfigurationProperties(prefix = "personbean")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> list;
    private String[][] mulArr;
    private Dog[] dogs;
    private Dog dog;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public Dog[] getDogs() {
        return dogs;
    }

    public void setDogs(Dog[] dogs) {
        this.dogs = dogs;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String[][] getMulArr() {
        return mulArr;
    }

    public void setMulArr(String[][] mulArr) {
        this.mulArr = mulArr;
    }

    @Override
    public String toString() {
        System.out.println("多维数组");
        for (String[] strings : mulArr) {
            for (String string : strings) {
                System.out.println(string);
            }
        }
        System.out.println("数组符合对象");
        for (Dog dog1 : dogs) {
            System.out.println(dog1);
        }
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", list=" + list +
                ", dog=" + dog +
                '}';
    }
}

[注]:1.yaml是没有办法像spring配置文件那样做对象引用 -- ref 的,只能做值引用。

          2.@ConfigurationProperties(prefix = "personbean")用于指明从yaml文件中的哪个对象获取值。

          3.yaml可用~表示赋值null。

          4.yaml支持松散绑定,last-name属性等价于lastName。(-符号后紧跟的字母大写)

          5.yaml自动根据字段名匹配赋值,而properties需要配合@Value用SPEL取值后赋值。

          6.一般来说,我们如果确定只要其中一个或几个值而不是全部,会选择用properties+@Value,但是大多数情况下还是会选择yaml。

          7.yaml中可以封装对象(复杂类型),而properties最多支持一个数组,@Value没有办法注入复杂类型。

          8.yaml支持JSR-303数据校验,可以在字段增加一层过滤器验证,保证数据的合法性。

4.构建测试

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    private Person person;

    @Autowired
    private Dog dog;

    @Test
    void contextLoads() {
        System.out.println(person);
        System.out.println(dog);
        System.out.println(person.getDog()==dog);
    }

}

5.执行结果

3.yaml vs propertie

对比一下使用properties赋值:

A.@PropertySource导入properties、使用SPEL配合@Value手动取值并赋值

这中方式可以将实体类赋值与主配置文件解耦,更清晰,但是比较难以使用。

dog_name=小白
dog_age=4
person_name=zzt
person_age=22
happy=true
birth=1999/4/14
list=code,music
@Component
@PropertySource(value = "classpath:bean.properties")
public class Person {
    @Value("${person_name}")
    private String name;
    @Value("${person_age}")
    private Integer age;
    @Value("${happy}")
    private Boolean happy;
    @Value("${birth}")
    private Date birth;
    // 没有办法用properties赋值
    private Map<String,Object> maps;
    @Value("${list}")
    private List<Object> list;
    // 没有办法用properties(正确)赋值
    private String[][] mulArr;
    // 没有办法用properties赋值
    private Dog[] dogs;
    // 没有办法用properties赋值
    private Dog dog;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public Dog[] getDogs() {
        return dogs;
    }

    public void setDogs(Dog[] dogs) {
        this.dogs = dogs;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String[][] getMulArr() {
        return mulArr;
    }

    public void setMulArr(String[][] mulArr) {
        this.mulArr = mulArr;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", list=" + list +
                ", dog=" + dog +
                '}';
    }
}

B.@ConfigurationProperties在主配置的properties指定所属对象,并使用prefix指定对象

application.properties

person.name=zjm
person.age=23
person.happy=true
person.birth=1998/5/23
person.list=wwz,zyf,zzt
person.dog.name=小黑
person.dog.age=4
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> list;
    private String[][] mulArr;
    private Dog[] dogs;
    private Dog dog;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public Dog[] getDogs() {
        return dogs;
    }

    public void setDogs(Dog[] dogs) {
        this.dogs = dogs;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String[][] getMulArr() {
        return mulArr;
    }

    public void setMulArr(String[][] mulArr) {
        this.mulArr = mulArr;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", list=" + list +
                ", dog=" + dog +
                '}';
    }
}

[注]:1.如果一定要使用properties,需要设置文件编码为UTF-8。

执行结果:

2.当同时存在application.properties和application.yaml,如果在两个配置文件中配置了相同的属性,以properties为准,不重复的配置全部采取(SpringBoot先读取properties)。

3.对于字符串类型的值,我们加不加' '和" "都一样,但如果一定要使用,他们之间还是有差距的:单引号具有转义功能,而双引号不具有转义功能

@Component
@ConfigurationProperties(prefix = "personbean")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> list;
    private String[][] mulArr;
    private Dog[] dogs;
    private Dog dog;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public Dog[] getDogs() {
        return dogs;
    }

    public void setDogs(Dog[] dogs) {
        this.dogs = dogs;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String[][] getMulArr() {
        return mulArr;
    }

    public void setMulArr(String[][] mulArr) {
        this.mulArr = mulArr;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", list=" + list +
                ", dog=" + dog +
                '}';
    }
}
personbean:
  name: "zzt \n zjm"

双引号会将原本的转义字符按照转义的含义进行输出。

personbean:
  name: 'zzt \n zjm'

单引号做的操作实际上是,为我们的转义字符\前面加上一个\,也就是单引号实际上的内容是zzt \\n zjm。

4.JSR-303校验(转载:https://www.jianshu.com/p/554533f88370)

JSR-303用于判断数据的合法性,若数据不合法,则不会进行注入。

A.导入依赖

        <!--JSR-303校验-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

B.启动校验 @Validated 

@Component
@ConfigurationProperties(prefix = "dogbean")
@Validated
public class Dog {

    @Email(message = "邮件地址不合法!")
    private String name;

    private Integer age;

    public Dog() {
    }

    public Dog(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

C.执行结果

5.SpringBoot多环境切换

        在实际开发中,我们会采用多环境的方式,做到开发和测试分离。

A.properties切换环境

使用 spring.profiles.active 选择要使用的环境:

.

没有激活其他环境时,使用的是application.properties中的环境

使用spring.profiles.active可以激活其他环境,配置文件名为 application-环境名.properties。

B.yaml切换环境

yaml多环境是不需要编写多个文件分别激活的,没有配置spring.config.activate.on-profile的环境就是默认环境。

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值