一、yaml配置注入

1、配置文件

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

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

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

比如我们可以在配置文件中修改Tomcat 默认启动的端口号!测试一下!

  1. server.port=8081

2、yaml概述

YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)

这种语言以数据作为中心,而不是以标记语言为重点!

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

传统xml配置:

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

yaml配置:

  1. server
  2. prot: 8080

3、yaml基础语法

说明:语法要求严格!

1、空格不能省略

2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。

3、属性和值的大小写都是十分敏感的。

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

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

  1. k: v

注意:

  • “ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
    比如 :name: “kuang \n shen” 输出 :kuang 换行 shen
  • ‘’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
    比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen

对象、Map(键值对)

  1. #对象、Map格式
  2. k:
  3. v1:
  4. v2:

在下一行来写对象的属性和值得关系,注意缩进;比如:

  1. student:
  2. name: qinjiang
  3. age: 3

行内写法

  1. student: {name: qinjiang,age: 3}

数组( List、set )

用 - 值表示数组中的一个元素,比如:

  1. pets:
  2. - cat
  3. - dog
  4. - pig

行内写法

  1. pets: [cat,dog,pig]

修改SpringBoot的默认端口号

配置文件中添加,端口号的参数,就可以切换端口;

  1. server:
  2. port: 8082

二、注入配置文件

yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!

1、yaml注入配置文件

1、在springboot项目中的resources目录下新建一个文件 application.yml

2、编写一个实体类 Dog;

  1. package com.kuang.springboot.pojo;
  2. @Component //注册bean到容器中
  3. public class Dog {
  4. private String name;
  5. private Integer age;
  6. //有参无参构造、get、set方法、toString()方法
  7. }

3、思考,我们原来是如何给bean注入属性值的!@Value,给狗狗类测试一下:

  1. @Component //注册bean
  2. public class Dog {
  3. @Value("旺财")
  4. private String name;
  5. @Value("18")
  6. private Integer age;
  7. }

4、在SpringBoot的测试类下注入狗狗输出一下;

  1. @SpringBootTest
  2. class DemoApplicationTests {
  3. @Autowired //将狗狗自动注入进来
  4. Dog dog;
  5. @Test
  6. public void contextLoads() {
  7. System.out.println(dog); //打印看下狗狗对象
  8. }
  9. }

结果成功输出,@Value注入成功,这是我们原来的办法

5、我们在编写一个复杂一点的实体类:Person 类

  1. @Component //注册bean到容器中
  2. public class Person {
  3. private String name;
  4. private Integer age;
  5. private Boolean happy;
  6. private Date birth;
  7. private Map<String,Object> maps;
  8. private List<Object> lists;
  9. private Dog dog;
  10. //有参无参构造、get、set方法、toString()方法
  11. }

6、我们来使用yaml配置的方式进行注入,大家写的时候注意区别和优势,我们编写一个yaml配置!

  1. person:
  2. name: qinjiang
  3. age: 3
  4. happy: false
  5. birth: 2000/01/01
  6. maps: {k1: v1,k2: v2}
  7. lists:
  8. - code
  9. - girl
  10. - music
  11. dog:
  12. name: 旺财
  13. age: 1

7、我们刚才已经把person这个对象的所有值都写好了,我们现在来注入到我们的类中!

  1. /*
  2. @ConfigurationProperties作用:
  3. 将配置文件中配置的每一个属性的值,映射到这个组件中;
  4. 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
  5. 参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
  6. */
  7. // 在文档中,导入配置文件处理器,配置文件进行绑定就会有提示,需要重启
  8. @Component //注册bean
  9. @ConfigurationProperties(prefix = "person")
  10. public class Person {
  11. private String name;
  12. private Integer age;
  13. private Boolean happy;
  14. private Date birth;
  15. private Map<String,Object> maps;
  16. private List<Object> lists;
  17. private Dog dog;
  18. }

9、确认以上配置都OK之后,我们去测试类中测试一下:

  1. @SpringBootTest
  2. class DemoApplicationTests {
  3. @Autowired
  4. Person person; //将person自动注入进来
  5. @Test
  6. public void contextLoads() {
  7. System.out.println(person); //打印person信息
  8. }
  9. }

结果:所有值全部注入成功

注意:将配置文件的key 值 和 属性的值设置为不一样,则结果输出为null,注入失败

2、加载指定的配置文件

@PropertySource 加载指定的配置文件;

@configurationProperties:默认从全局配置文件中获取值;

1、我们去在resources目录下新建一个person.properties文件

  1. name=shuai

2、然后在我们的代码中指定加载person.properties文件

  1. @PropertySource(value = "classpath:person.properties")
  2. @Component //注册bean
  3. public class Person {
  4. @Value("${name}")
  5. private String name;
  6. ......
  7. }

3、再次输出测试一下:指定配置文件绑定成功!

3、配置文件占位符

配置文件还可以编写占位符生成随机数

  1. person:
  2. name: qinjiang${random.uuid} # 随机uuid
  3. age: ${random.int} # 随机int
  4. happy: false
  5. birth: 2000/01/01
  6. maps: {k1: v1,k2: v2}
  7. lists:
  8. - code
  9. - girl
  10. - music
  11. dog:
  12. name: ${person.hello:other}_旺财
  13. age: 1

我们上面采用的yaml方法都是最简单的方式,开发中最常用的;也是springboot所推荐的!

结论:

配置yml和配置properties都可以获取到值 , 强烈推荐 yml;

三、JSR303数据校验

1、先看看如何使用

Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;

  1. @Component //注册bean
  2. @ConfigurationProperties(prefix = "person")
  3. @Validated //数据校验
  4. public class Person {
  5. @Email(message="邮箱格式错误") //name必须是邮箱格式
  6. private String name;
  7. }

运行结果 :default message [不是一个合法的电子邮件地址];

2、常见参数

  1. @NotNull(message="名字不能为空")
  2. private String userName;
  3. @Max(value=120,message="年龄最大不能查过120")
  4. private int age;
  5. @Email(message="邮箱格式错误")
  6. private String email;

注意:其他注解可以在网上查询

四、多环境切换

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

1、多配置文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;

例如:

application-test.properties 代表测试环境配置

application-dev.properties 代表开发环境配置

但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件

我们需要通过一个配置来选择需要激活的环境:

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

2、yaml的多文档块

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

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

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

3、配置文件加载位置

外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!

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

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

五、自动配置原理

1、自动装配原理的精髓!

1、SpringBoot启动会加载大量的自动配置类

2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

xxxxAutoConfigurartion:自动配置类;给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

2、了解:@Conditional

了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

我们怎么知道哪些自动配置类生效?

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

  1. #开启springboot的调试类
  2. debug=true

Positive matches:(自动配置类启用的:正匹配)

Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

Unconditional classes: (没有条件的类)

【演示:查看输出的日志】