🔍
📢

Spring Boot application.properties和YAML配置文件application.yml

 


 

一、全局配置文件

1、分类:(文件名固定)

(1)application.properties
(2)application.yml
(3)以上两种文件作用类似,但是内部写法有些区别。

2、作用:

  修改 SpringBoot 自动配置的默认值。

3、什么是yml

  YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,其以“数据为中心”,比json、xml文件更适合做配置文件。

 
【xml配置文件的写法举例:】
<server>
    <port>8090</port>
</server>

【properties配置文件的写法举例:】
server.port = 8090

【yml配置文件的写法举例:】
server:
    port: 8090  # 注意,8090 与 : 间有个空格。
    
使用Idea 编写yml配置文件时,若没有提示,可以下个yml插件。
 

二、YAML语法

1、基本语法

(1)使用缩进表示各元素间的层级关系。其中使用空格来缩进,不能使用Tab键。
(2)空格数不做要求,但是相同层级元素的左侧需要对齐。
(3)大小写敏感。

2、支持数据格式

(1)支持对象(键值对的集合,key:value)
  字符串可以不用使用双引号或单引号圈起来
  双引号圈住时不会转义字符串中的特殊字符
  单引号圈住时会转义字符串中的特殊字符

 
【分层写法:】
对象名:
    k1: v1
    k2: v2
    #注意  : 后面有个空格。
    
【行内写法:】
对象名:{k1: v1,k2: v2}
 

(2)数组:一组按顺序排列的值

 
【分层写法:】
数组名:
    - 元素1
    - 元素2
    
【行内写法:】
数组名:[元素1,元素2,元素3]
 

(3)字面量:单个的、不可再分的值(数字、字符串、布尔值、日期)

 

 

三、配置文件值的映射

  将配置文件中配置的属性值映射到组件中。

1、@ConfigurationProperties

  用于 告诉 SpringBoot 将本类中的属性与配置文件中的内容相关联(绑定)。其有个参数 prefix 用于找到配置文件中指定的属性。
注:
  只有容器中的组件才能使用此标记的功能。需给其加个@Component注解。

举例:
  用到四个类:
    HelloworldApplication.java 用于启动SpringBoot应用。
    HelloWorldController.java 用于处理浏览器的请求。
    People.java 配置文件映射的实体类。
    Teacher.java 作为People中的一个对象。

  配置文件
    application.yml 与 application.properties二者选其一即可。

 

 

 
【举例:多余的注释就不写了】
【HelloworldApplication.java】
package com.example.helloworld;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloworldApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloworldApplication.class, args);
    }

}

【HelloWorldController.java】
package com.example.helloworld.controller;

import com.example.helloworld.entity.People;
import com.example.helloworld.entity.Teacher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloWorldController {
    //自动注入对象
  @Autowired
  People people;
  @Autowired
  Teacher teacher;

  @ResponseBody
  @RequestMapping("/hello")
  public String show() {

    return people.toString() + teacher.toString();
  }
}

【People.java】
package com.example.helloworld.entity;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用于测试各种类型的映射
 */
@Component
@ConfigurationProperties(prefix = "people")
public class People {

  private Integer age;
  private Boolean boss;
  private List<String> cityList;
  private Date date;
  private Map<String, Object> map;
  private String name;
  private Teacher teacher;

  public Integer getAge() {
    return age;
  }

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

  public Boolean getBoss() {
    return boss;
  }

  public void setBoss(Boolean boss) {
    this.boss = boss;
  }

  public List<String> getCityList() {
    return cityList;
  }

  public void setCityList(List<String> cityList) {
    this.cityList = cityList;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }

  public Map<String, Object> getMap() {
    return map;
  }


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

  public String getName() {
    return name;
  }

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

  public Teacher getTeacher() {
    return teacher;
  }


  public void setTeacher(Teacher teacher) {
    this.teacher = teacher;
  }

  @Override
  public String toString() {
    return "People{" +
        "age=" + age +
        ", boss=" + boss +
        ", cityList=" + cityList +
        ", date=" + date +
        ", map=" + map +
        ", name='" + name + '\'' +
        ", teacher=" + teacher +
        '}';
  }
}

【Teacher.java 】
package com.example.helloworld.entity;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "people.teacher")
public class Teacher {

  private Integer age;
  private String name;

  public Integer getAge() {
    return age;
  }

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

  public String getName() {
    return name;
  }

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

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

【application.yml (注意层级关系以及空格)】
people:
  age: 18
  boss: false
  cityList:
    - Beijing
    - Nanjing
  date: 2019/7/21
  map: {k1: v1, k2: v2}
  name: Tom
  teacher:
    age: 30
    name: Jarry

【application.properties(使用这个也行)】
people.age=18
people.boss=false
people.date=2019/7/21
people.city-list=Beijing, Nanjing
people.map.k1=v1
people.map.k2=v2
people.name=Tom
people.teacher.age=25
people.teacher.name=Jarry

【注:】
配置文件优先级问题,后续会讲。此处若application.properties与application.yml同时存在,
则对于重复部分application.properties优先级高于application.yml(即覆盖掉application.yml中重复的内容)。
 

当写@ConfigurationProperties时,会有相关提示信息,提示下载配置文件处理器,功能是:当配置文件进行映射时会有相关提示。

点击Open Documentation后,在联网状态下会进入一个网址,找到相关依赖信息。

复制下来后,粘贴在项目的pom.xml的相应位置中。

重启一下Idea即可。

 

2、@Value

(1)格式:

@Value("${key}")
@Value("#{表达式}")
@Value("字面量(字符串、日期、数字、布尔值)")

(2)举例:
  使用@Value时,也需要@Component组件,且value是一个个映射,需要自己输入值。

 
【举例:仅修改People.java】
package com.example.helloworld.entity;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 用于测试各种类型的映射
 */
@Component
public class People {

  @Value("#{11*13}")
  private Integer age;
  @Value("true")
  private Boolean boss;
  @Value("${cityList:1,2,3}")
  private List<String> cityList;

  public Integer getAge() {
    return age;
  }

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

  public Boolean getBoss() {
    return boss;
  }

  public void setBoss(Boolean boss) {
    this.boss = boss;
  }

  public List<String> getCityList() {
    return cityList;
  }

  public void setCityList(List<String> cityList) {
    this.cityList = cityList;
  }

  @Override
  public String toString() {
    return "People{" +
        "age=" + age +
        ", boss=" + boss +
        ", cityList=" + cityList +
        '}';
  }
}
 

 

 (3)@Value与@ConfigurationProperties的区别

@ConfigurationProperties                              @Value
可以批量配置属性的映射                                 需要手动一个个的配置
支持松散绑定(比如lastName可以写成last_name)           不支持松散绑定
不支持表达式                                          支持表达式
支持JSR-303验证 (@Validated)                        不支持JSR-303验证

3、@PropertySource与@ImportResource

(1)@PropertySource用于加载指定位置的文件,只能用于properties,可以加载多个配置文件。

@PropertySource(value = "{classpath:XXX.properties}")

(2)@ImportResource用于导入外置的配置文件(比如Spring的配置文件)。

@ImportResource(locations = "{classpath:XXX.xml}")

 

4、配置文件中的占位符

(1)可以在配置文件中,添加一些随机数(比如 ${random.int})。
(2)可以通过占位符获取之前已经设置的值。
  ${random.int} 用于获取一个随机的int值
  ${name : Rick} 用于设置默认值。若之前没有name配置,则默认值为Rick

 
【举例:改变application.properties】
people.age=${random.int}
people.boss=false
people.date=2019/7/21
people.city-list=Beijing, Nanjing
people.map.k1=v1
people.map.k2=v2
people.name=Tom
people.teacher.age=${people.age}
people.teacher.name=${name : Rick}
 

 

5、profile

  profile是对不同环境(比如开发、生产、测试环境)提供的不同配置功能的支持,可以通过激活或指定参数等方式快速切换环境。
(1)存在多个profile配置文件时,
  文件名格式为:application-{profile}.properties 或 application-{profile}.yml
  但是系统默认调用全局配置文件(application.properties 或 application.yml).
  比如创建一个 profile文件,文件名为 application-test.properties
  若想调用某个指定的profile,可以在 全局配置文件中通过(spring.profiles.active)激活。
  比如: spring.profiles.active = test

(2)对于yml文件可以存在profile文档块的方式,使用(---)分割,并在全局配置文件中激活。

 
【举例:application.yml中】
server:
  port: 7090
spring:
  profiles:
    active: test2
---
server:
  port: 8090
spring:
  profiles:test

---
server:
  port: 9090
spring:
  profiles:test2
 

(3)在IDEA中配置profiles激活。
  点开配置的下拉,找到Edit Configurations...  添加需要激活的环境即可。

--spring.profiles.active=test

 

(4)通过命令行参数的方式。
  执行打包命名后,执行jar包时,在其后输入添加需要激活的环境即可。

java -jar 包名 --spring.profiles.active=test

 

6、配置文件加载路径、以及路径优先级问题

(1)自动扫描:
  SpringBoot启动后,会自动扫描以下目录下的 application.properties 或者 application.yml,并让其作为默认的配置文件。

 
优先级从高到低。file指的是当前项目的根目录。classpath指的是当前resource路径
file:./config/
file:./
classpath:./config/
classpath:./

这些路径均会被加载,当配置文件有重复内容时,高优先级的会覆盖掉低优先级的,最终所有路径下的配置文件形成互补配置。
 

(2)修改默认配置
  在项目打包后,可以通过命令行参数的形式,启动项目的同时,指定配置文件的位置。是一种用于运维时补救的措施。该配置文件会与项目中的配置文件形成互补配置。

java -jar 包名 --spring.config.location=XXX.yml