SpringBoot——SpringBoot配置文件、yaml语法、JSR303校验、多环境切换Profile

目录

  • 一、SpringBoot配置文件
  • 二、yaml概述
    • 1、基本语法
    • 2、值的写法
  • 三、配置文件值注入
    • 1、yaml注入配置文件
  • 四、@Value获取值和@ConfigurationProperties获取值比较
    • 1、配置文件注入值数据校验
    • 2、@PropertySource&@ImportResource&@Bean注解
    • 3、配置文件占位符
  • 五、JSR303校验
  • 六、多环境切换 Profile
    • 1、多配置文件
    • 2、yaml的多文档块
    • 3、配置文件的加载位置
      在这里插入图片描述

一、SpringBoot配置文件

跳转到目录
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的;

  • application.properties

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

    • 语法结构 :key:空格 value

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

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

server.port=8081

二、yaml概述

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

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

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

yaml配置:

server:
  port: 8081

传统xml配置:

<server>
	<port>8081port>
server>

yaml语法

跳转到目录
说明:语法要求严格!

1、空格不能省略

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

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

1、基本语法

跳转到目录
k:(空格)v:表示一对键值对(空格必须有);

空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的

server:
    port: 8081
    path: /hello

属性和值也是大小写敏感;

2、值的写法

跳转到目录

字面量:普通的值(数字,字符串,布尔)

跳转到目录
​ k: v:字面直接来写;

注意: 字符串默认不用加上单引号或者双引号;

  • “”:双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思

name: “zhangsan \n lisi”:输出;zhangsan 换行 lisi

  • ’ ':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据

name: ‘zhangsan \n lisi’:输出;zhangsan \n lisi

对象、Map(属性和值)(键值对):

跳转到目录

​ k: v:在下一行来写对象的属性和值的关系;注意缩进

​ 对象还是k: v的方式

friends:
	lastName: zhangsan
	age: 20

行内写法:

friends: {lastName: zhangsan,age: 18}

数组(List、Set):

跳转到目录

用- 值表示数组中的一个元素

pets:
 - cat
 - dog
 - pig

行内写法

pets: [cat,dog,pig]

三、配置文件值注入

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

yaml注入配置文件

跳转到目录

1、在springboot项目中的resources目录下新建一个文件 application.yml
2、编写一个实体类 Dog;
package com.sunny.springboot.pojo;

@Component  //注册bean到容器中
public class Dog {
    private String name;
    private Integer age;
    private Boolean eat;
    
    //有参无参构造、get、set方法、toString()方法  
}
3、思考,我们原来是如何给bean注入属性值的!@Value,给狗狗类测试一下:
 /**
   *
   * @Value()注解的作用同下
   *
   * 
   *      
   * 
   */
    //@Value("${Dog.last-name}")
    @Value("阿黄")
    private String name;
    @Value("#{1*18}")
    private Integer age;
    @Value("false")
    private Boolean eat;
4、在SpringBoot的测试类下注入狗狗输出一下;
@SpringBootTest
class DemoApplicationTests {

    @Autowired //将狗狗自动注入进来
    Dog dog;

    @Test
    public void contextLoads() {
        System.out.println(dog); //打印看下狗狗对象
    }
}
结果成功输出,@Value注入成功,这是我们原来的办法对吧。

SpringBoot——SpringBoot配置文件、yaml语法、JSR303校验、多环境切换Profile_第1张图片

5、我们在编写一个复杂一点的实体类:Person 类
@Component //注册bean到容器中
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;
    
    //有参无参构造、get、set方法、toString()方法  
}
6、我们来使用yaml配置的方式进行注入,大家写的时候注意区别和优势,我们编写一个yaml配置!
person:
  name: qinjiang
  age: 3
  happy: false
  birth: 2000/01/01
  maps: {k1: v1,k2: v2}
  lists:
   - code
   - girl
   - music
  dog:
    name: 旺财
    age: 1
7、我们刚才已经把person这个对象的所有值都写好了,我们现在来注入到我们的类中!
  • @ConfigurationProperties(prefix = "bean的id")
    这个组件必须在容器中,才能使用该注解的功能;
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/
@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;
}
8、IDEA 提示,springboot配置注解处理器没有找到,让我们看文档,我们可以查看文档,找到一个依赖!

<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-configuration-processorartifactId>
  <optional>trueoptional>
dependency>
9、确认以上配置都OK之后,我们去测试类中测试一下:
@SpringBootTest
class DemoApplicationTests {
    @Autowired
    Person person; //将person自动注入进来

    @Test
    public void contextLoads() {
        System.out.println(person); //打印person信息
    }
}

yaml配置注入到实体类完全OK!

10、除了使用yaml配置,也可以使用application.properties全局配置文件:
person.last-name=zhangsan
person.age=18
person.birth=2020/3/25
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=dog
person.dog.age=4

同样使用@ConfigurationProperties: 告诉SpringBoot将本类中的所有属性和配置文件中的相关配置进行绑定; 这样也同样可以和yaml同样的效果!

注意】properties配置文件在写中文的时候,会有乱码 , 我们需要去IDEA中设置编码格式为UTF-8;

settings–>FileEncodings 中配置;

11、除了全局的配置文件外,如果要加载指定的配置文件

@PropertySource 注解

在resources目录下新建一个person.properties文件

person.last-name=zhangsan
person.age=18
person.birth=2020/3/25
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=dog
person.dog.age=4

此时需要使用@PropertySource(value = "classpath:person.properties")这个注解; 并配合@Value注解来使用;

举个栗子: 这是一个配置类(和spring.xml实现同样的功能)

@Configuration
@ComponentScan("com.sunny")
@PropertySource("classpath:db.properties")
@EnableTransactionManagement // 事务处理的注解
public class AppConfig {

    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Value("${jdbc.initialSize}")
    private int initialSize;

    // 连接池对象
    @Bean // bean的id就是dataSource,也可以起一个
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setInitialSize(initialSize);
        return ds;
    }

    // 事务管理器对象;这里传的ds对象,就是上面的连接池对象,它会自动找ds对象
    @Bean
    public DataSourceTransactionManager txManager(DataSource ds){
        return new DataSourceTransactionManager(ds);
    }
}

db.properties

#key=value
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc
jdbc.username=root
jdbc.password=1111
jdbc.initialSize=2

注意:

  • 将配置文件的key 值 和 属性的值设置为不一样,则结果输出为null,注入失败
  • 在配置一个person2,然后将 @ConfigurationProperties(prefix = “person2”) 指向我们的person2;

四 、@Value获取值和@ConfigurationProperties获取值比较

跳转到目录

@ConfigurationProperties @Value
功能 批量注入配置文件中的属性 一个个指定
松散绑定(松散语法) 支持 不支持
SpEL 不支持 支持
JSR303数据校验 支持 不支持
复杂类型封装 支持 不支持

1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加

2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下

3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性

4、复杂类型封装,yml中可以封装对象 , 使用value就不支持

结论:

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

  • 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @Value

  • 如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties;

1、配置文件注入值数据校验

@Validated 注解

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {

    /**
     * 
     *      
     * 
     */

   //lastName必须是邮箱格式
    @Email
    //@Value("${person.last-name}")
    private String lastName;
    //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;

    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

2、@PropertySource&@ImportResource&@Bean

跳转到目录
@PropertySource:加载指定的配置文件;

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行一一映射
 *
 * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
 *  @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
 *
 */
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
//@Validated
public class Person {

    /**
     * 
     *      
     * 
     */

   //lastName必须是邮箱格式
   // @Email
    //@Value("${person.last-name}")
    private String lastName;
    //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;

@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效

Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;

想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上

//导入Spring的配置文件让其生效
@ImportResource(locations = {"classpath:beans.xml"})
@SpringBootApplication
public class Application {

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

不来编写Spring的配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="helloService" class="com.atguigu.springboot.service.HelloService">bean>
beans>

SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式

1、配置类@Configuration------>Spring配置文件

2、使用@Bean给容器中添加组件

/**
 * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
 *
 * 在配置文件中用标签添加组件
 *
 */
@Configuration
public class MyAppConfig {

    //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置类@Bean给容器中添加组件了...");
        return new HelloService();
    }
}

SpringBoot 自动装配都是用的配置类!

3、配置文件占位符

跳转到目录

  • 随机数
  • 占位符获取之前配置的值,如果没有可以是用: 指定默认值
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
Person:
  name: gzy${random.uuid}
  age: ${random.int}
  happy: false
  birth: 1998/2/11
  maps: {k1: v1, k2: v2}
  lists:
    - code
    - girl
    - music
  dog:
  	# 使用Person.hello这个配置的值,如果没有这个配置,则使用指定的默认值hello
    name: ${Person.hello:hello}_旺财
    age: 1

五、JSR303校验

跳转到目录

  • Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。

  • 使用数据校验,可以保证数据的正确性;

常见参数:

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

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.
    
Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  
    
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 Date 和 Calendar 对象是否在当前时间之前  
@Future     验证 Date 和 Calendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则

.......等等
除此以外,我们还可以自定义一些数据校验规则

六、多环境切换 Profile

跳转到目录

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

1、多配置文件

跳转到目录

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

例如:

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

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

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

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

2、yaml的多文档块

跳转到目录

  • properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !
server:
  port: 8081
spring:
  profiles:
    active: dev
---
server:
  port: 8083
spring:
  profiles: dev # 配置环境的名称

---
server:
  port: 8084
spring:
  profiles: prod

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

3、配置文件的加载位置

跳转到目录

  • 官方外部配置文件说明参考文档
    SpringBoot——SpringBoot配置文件、yaml语法、JSR303校验、多环境切换Profile_第2张图片

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

优先级1:项目路径下的config文件夹配置文件
优先级2:项目路径下配置文件
优先级3:资源路径下的config文件夹配置文件
优先级4:资源路径下配置文件
  • 优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置

我们在最低级的配置文件中设置一个项目访问路径的配置来测试互补问题;

#配置项目的访问路径
server.servlet.context-path=/zy
  • 我们还可以通过spring.config.location来改变默认的配置文件位置

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;这种情况,一般是后期运维做的多,相同配置,外部指定的配置文件优先级最高;

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties

你可能感兴趣的:(SpringBoot)