• SpringBoot之yaml语法、配置文件、多环境切换


    SpringBoot Banner生成网站:https://www.bootschool.net/ascii
    在SpringBoot项目的resource目录下,新建一个banner.txt文件,将自定义的banner内容放到文件里面。

    快速构建SpringBoot项目网站:https://start.spring.io/


    yaml语法讲解

    配置文件

    SpringBoot使用一个全局的配置文件,配置文件名称是固定的

    • application.properties
      语法结构:key=value

    • application.yml
      语法结构:key:空格 value

    配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;



    YAML

    YAML是一个可读性高,用来表达数据序列化的格式。
    YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。


    标记语言

    以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,对比下yaml和xml

    yaml配置:

    server:
    	port:8080
    
    • 1
    • 2

    xml配置:

    <server>
    	<port>8081</port>
    </server>
    
    • 1
    • 2
    • 3


    YAML语法

    基础语法:

    k:(空格) v
    
    • 1

    以此来表示一堆键值对(空格不能省略);以空格的缩进来控制层级关系,只要是左边对齐的一列数据都是同一层级的。


    注意:属性和值的大小写都是十分敏感的。

    server:
    	port:8081
    	path:/hello
    
    • 1
    • 2
    • 3

    值的写法

    字面量:普通的值[数字,布尔值,字符串]

    k:v
    
    • 1

    字面量直接写在后面就可以,字符串默认不用加上双引号或者单引号;

    “” 双引号,不会转义字符串里面的特殊字符,特殊字符会作为本身想表达的意思;
    比如:name:"zhang \n san " 输出:zhang 换行 san

    # k=v
    # 对空格的要求十分高!
    # 普通的key-value
    
    # 注入到我们的配置类中!
    
    name:luxifa
    
    # 对象
    student:
      name:luxifa
      age:3
    
    # 行内写法
    
    student:{name:luxifa,age:3}
    
    # 数组
    pets:
      - cat
      - dog
      - pig
      
    pets:[cat,dog,pig]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24


    注入配置文件

    1.如果要使用properties配置文件可能导入时存在乱码现象,需要在IDEA中进行调整,在这里我们使用yml文件,将默认的application.properties后缀修改为yml

    2.导入配置文件处理器

    <!--导入配置文件处理器,配置文件进行绑定就会有提示-->
    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-configuration-processor</artifactId>
         <optional>true</optional>
     </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.编写yml配置文件

    person:
    	name:luxifa${random.uuid}
    	age:${random.int}
    	happy:true
    	birth:2022/06/17
    	maps:{k1:v1,k2:v2}
    	lists:
    		- code
    		- music
    		- girl
    	dog:
    		name:${person.hello:hello}_旺财
    		age:3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.在SpringBoot的主程序的同级目录下建包,只有这样,主程序才会对这些类生效;我们建一个pojo的包放入我们的Person类和Dog类;

    /*
    @configurationProperties作用:
    将配置文件中配置的每一个属性的值,映射到这个组件中;
    告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
    参数prefix = “person”:将配置文件中的person下面的所有属性--对应
    
    只有这个组件是容器中的组件,才能使用容器剔红的@ConfigurationPreperties功能
    */
    @Component  //注册bean
    @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> lists;
    	private Dog dog;
    
    	public person(){}
    
    	public Person(String name,Integer age,Boolean happy,Date birth,Map<String,Object> maps,List<Object> lists,Dog dog) {
    		this.name = name;
    		this.age = age;
    		this.happy = happy;
    		this.birth = birth;
    		this.maps = maps;
    		this.lists = lists;
    		this.dog = dog;
    	}
    	
    	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> getLists() {
            return lists;
        }
    
        public void setLists(List<Object> lists) {
            this.lists = lists;
        }
    
        public Dog getDog() {
            return dog;
        }
    
        public void setDog(Dog dog) {
            this.dog = dog;
        }
    	@Override
        public String toString() {
            return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
        }
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    配置文件除了yml,还有常用的properties,properties配置文件在写中文的时候,会有乱码,需要在IDEA中设置编码格式为UTF-8;
    setting–>FileEncodings中配置;

    类和文件直接关联,我们使用的是@ConfigurationPerperties的方式,还有一种方式是@value

    @Component //注册bean
    	//直接使用@value
    	@value("${person.name}")  //从配置文件中取值
    	private String name;
    	@value("${11*2}")  //# {SPEL} spring表达式
    	private Integer age;
    	@value("true")  //# 字面量
    	private Boolean happy;
        
        。。。。。。
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这样使用起来并不友好,我们需要为每个属性单独注解赋值,比较麻烦;
    功能对比图

    @ConfigurationProperties@Value
    功能批量注入配置文件中的属性一个个指定
    松散绑定(松散语法)支持不支持
    SpEL不支持支持
    JSR303数据校验支持不支持
    复杂类型封装支持不支持
    • cp只需要写一次即可,value则需要每个字段都添加
    • 松散绑定:比如在yml中写的是last-name,这个和lastName是一样的,-后面跟着的字母默认是大写的,这就是松散绑定。
    • JSR303数据校验,指可以在字段上增加一层过滤器验证,可以保证数据的合法性
    • 复杂类型封装,yml中可以封装对象,使用@value就不支持

    结论:

    • 配置yml和配置properties都可以获取到值,强烈推荐yml
    • 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用@value
    • 如果说,我们专门编写了一个JavaBean来和配置文件进行映射,就直接使用@configurationProperties,不要犹豫!

    注入配置案例1:

    @Component
    public class Dog {
    
    	@Value("旺财")
    	private String name;
    	@Value("3")
    	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;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    @SpringBootTest
    class Springboot01ConfigApplicationTests {
    	
    	@Autowired
    	private Dog dog;
    
    	@Test
    	void contextLoads() {
    		System.out.println(dog);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出结果:

    Dog{name='旺财',age=3}
    
    • 1

    注入配置案例2:

    @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> lists;
    	private Dog dog;
    
    	public person(){}
    
    	public Person(String name,Integer age,Boolean happy,Date birth,Map<String,Object> maps,List<Object> lists,Dog dog) {
    		this.name = name;
    		this.age = age;
    		this.happy = happy;
    		this.birth = birth;
    		this.maps = maps;
    		this.lists = lists;
    		this.dog = dog;
    	}
    	
    	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> getLists() {
            return lists;
        }
    
        public void setLists(List<Object> lists) {
            this.lists = lists;
        }
    
        public Dog getDog() {
            return dog;
        }
    
        public void setDog(Dog dog) {
            this.dog = dog;
        }
    	@Override
        public String toString() {
            return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
        }
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    application.yml

    person:
    	name:luxifa${random.uuid}
    	age:${random.int}
    	happy:true
    	birth:2022/06/17
    	maps:{k1:v1,k2:v2}
    	lists:
    		- code
    		- music
    		- girl
    	dog:
    		name:${person.hello:hello}_旺财
    		age:3
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    @SpringBootTest
    class Springboot01ConfigApplicationTests {
    	
    	@Autowired
    	private Person person;
    
    	@Test
    	void contextLoads() {
    		System.out.println(person);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出结果:

    Person{name='luxifae9eeef60-500e-4476-be44-cda4cf78fcde',age=31706088789,happy=true,birth=Sat Nov 02 00:00:00 CST 2019,maps={k1=v1,k2=v2},lists=[code,music,girl],dog=Dog{name='hello_旺财',age=3}}
    
    • 1

    注入配置案例3:

    @Component
    //javaConfig 绑定配置文件的值,可以采取这些方式
    //加载指定的配置文件
    @PropertySource(value= "classpath:luxifa.properties")
    public class Person {
    
    	//SPEL表达式取出配置文件的值
    	@Value("${name}")
    	private String name;
    	private Integer age;
    	private Boolean happy;
    	private Date birth;
    	private Map<String,Object> maps;
    	private List<Object> lists;
    	private Dog dog;
    
    	public person(){}
    
    	public Person(String name,Integer age,Boolean happy,Date birth,Map<String,Object> maps,List<Object> lists,Dog dog) {
    		this.name = name;
    		this.age = age;
    		this.happy = happy;
    		this.birth = birth;
    		this.maps = maps;
    		this.lists = lists;
    		this.dog = dog;
    	}
    	
    	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> getLists() {
            return lists;
        }
    
        public void setLists(List<Object> lists) {
            this.lists = lists;
        }
    
        public Dog getDog() {
            return dog;
        }
    
        public void setDog(Dog dog) {
            this.dog = dog;
        }
    	@Override
        public String toString() {
            return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", happy=" + happy +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
        }
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    luxifa.properties

    name=luxifa
    
    • 1
    @SpringBootTest
    class Springboot01ConfigApplicationTests {
    	
    	@Autowired
    	private Person person;
    
    	@Test
    	void contextLoads() {
    		System.out.println(person);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出结果:

    Person{name='luxifa',age=null,happy=null,birth=null,maps=null,lists=null,dog=null}
    
    • 1


    JSR303数据校验

    spring-boot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心同一处理

    @Component  //注册bean
    @ConfigurationProperties(prefix = "person")
    @Validated  //数据校验
    public class Person {
    	
    	@Email //name必须是邮箱格式
    	private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    Constraint详细信息
    @Null被注释的元素必须为 null
    @NotNull被注释的元素必须不为 null
    @AssertTrue被注释的元素必须为 true
    @AssertFalse被注释的元素必须为 false
    @Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @DecimalMax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @Size(max, min)被注释的元素的大小必须在指定的范围内
    @Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
    @Past被注释的元素必须是一个过去的日期
    @Future被注释的元素必须是一个将来的日期
    @Pattern(value)被注释的元素必须符合指定的正则表达式
    @Email被注释的元素必须是电子邮箱地址
    @Length被注释的字符串的大小必须在指定的范围内
    @NotEmpty被注释的字符串的必须非空
    @Range被注释的元素必须在合适的范围内


    配置文件占位符

    随机数

    ${random.value}、${random.int}、${random.long}、${random.int(10)}等等
    
    • 1

    占位符引用其他属性的值,如果不存在可以设置默认值

    person:
    	name:luxifa${random.uuid}
    	age:${random.int}
    	happy:true
    	birth:2022/06/17
    	maps:{k1:v1,k2:v2}
    	lists:
    		- code
    		- music
    		- girl
    	dog:
    		name:${person.hello:hello}_旺财
    		age:3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13


    多环境切换

    profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;

    方式一:多配置文件
    我们在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml,用来指定多个环境配置;
    例如:application-test.properties代表测试环境配置 application-dev.properties代表开发环境配置
    但是SpringBoot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;我们需要通过一个配置来选择需要激活的环境;

    #比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;
    #我们启动SpringBoot,就可以看到已经切换到dev下的配置了;
    spring.profiles.active=dev
    
    • 1
    • 2
    • 3

    方式二:yml的多文档块
    和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件了,更加方便了

    server:
    	port:8081
    #选择要激活哪个环境快
    spring:
    	profiles:
    		active:prod
    
    ---
    server:
    	port:8083
    #配置环境的名称
    spring:
    	profiles:dev
    ---
    
    server:
    	port:8084
    spring:
    	profiles:prod  #配置环境的名称
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注意:如果yml和properties同时都配置了端口,并且没有激活其他环境,默认会使用properties配置文件



    配置文件加载位置

    springboot启动会扫描以下位置的application.properties或者application.yml文件作为Springboot的默认配置文件

    优先级1:项目路径下的config文件夹配置文件
    优先级2:项目路径下配置文件
    优先级3:资源路径下的config文件夹配置文件
    优先级4:资源路径下配置文件
    
    • 1
    • 2
    • 3
    • 4

    优先级由高到低,高优先级的配置会覆盖低优先级的配置;

  • 相关阅读:
    RHCSA认证考试---8.配置 autofs
    Kotlin(十一)Kotlin中的Object关键字
    MySQL主从复制和读写分离
    postman接口测试实战讲解
    秋招面经第一弹:百度一面-大数据开发工程师
    pcan二次开发文档 | PEAK-System Documentation
    面试题:打印课程
    消防设备电源监控系统在城市建筑中的应用
    【SCAU数据挖掘】数据挖掘期末总复习题库判断题及解析
    ffmpeg图片转YUV格式
  • 原文地址:https://blog.csdn.net/weixin_42594143/article/details/125440734