给配置文件赋值的几种方式,即yaml。
yaml
根据百度百科来看,yaml的“ml”就和html和xml的“ml”一样,也是一种标记语言,但是百度百科又说yaml它不是一种标记语言。那么,yaml他到底是不是标记语言呢?这里我们不做讨论。其实只需要知道,yaml是以数据作为中心,而不是以标记语言作为中心的。为了加深理解,我们需要创建一个项目来帮助我们理解。
1.首先,新建springboot项目,命名为springboot-yaml。(创建项目的步骤在此不做叙述)创建成功之后,我们会有如下的项目结构。
其中的src目录下的HELP.md、mvnw、mvnw.cmd和.gitignore文件,对于我们的项目来说并没有作用,所以我们选择将它们删除。
通常来说,springboot使用的是一个全局的配置文件,其作用是修改springboot自动配置的默认值,因为springboot在底层都会给我们自动配置好了,我们需要根据需要来修改默认值。配置文件的名称一般是固定的
application.properties:其语法结构是key=value,即name=jiaomubai;
application.yaml:其语法结构是key:空格value,即name: jiaomubai。一定要注意冒号后的空格,否则报错,会产生设置无效的后果。
yaml最强大的地方在于它可以给我们的实体类赋值,即键值对,列表,数组之类。
2.在与SpringbootYamlApplication文件同级的目录下建立一个新的实体类,为了方便,我们简单的创建一个Dog的实体。创建之前记得让Dog实体单独存在于pojo包中。
Dog.java文件:其中的构造函数和get()、set()和toString()方法都能通过Alt+Insert快捷键快捷选择。一定要记得添加上@Component。
package com.example.pojo;
import org.springframework.stereotype.Component;
//把这个实体类里的东西交给Spring管理,添加到Spring的组件里边
@Component
public class Dog {
//Dog的一般属性,名字和年龄
private String name;
private int age;
//无参构造函数
public Dog() {
}
//有参构造函数
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
//各个属性的get()和set()方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//toString()方法也不要忘记
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
除此之外,为了有一个较好的对照效果和测试效果,我们在当前目录下再新建一个class文件,命名为Person,并且让Dog作为Person的一个属性。
Person.java文件:
package com.example.pojo;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
public class Person {
//Person的一些基本属性,为了测试项目使用,无实际意义,可自行增删
private String p_name;
private int p_age;
private String sex;
private Date birthday;
private List<Object> list;
private Boolean happy;
private Map<String,Object> map;
private Dog dog;
public Person() {
}
public Person(String p_name, int p_age, String sex, Date birthday, List<Object> list, Boolean happy, Map<String, Object> map, Dog dog) {
this.p_name = p_name;
this.p_age = p_age;
this.sex = sex;
this.birthday = birthday;
this.list = list;
this.happy = happy;
this.map = map;
this.dog = dog;
}
public String getP_name() {
return p_name;
}
public void setP_name(String p_name) {
this.p_name = p_name;
}
public int getP_age() {
return p_age;
}
public void setP_age(int p_age) {
this.p_age = p_age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
public Boolean getHappy() {
return happy;
}
public void setHappy(Boolean happy) {
this.happy = happy;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Person{" +
"p_name='" + p_name + '\'' +
", p_age=" + p_age +
", sex='" + sex + '\'' +
", birthday=" + birthday +
", list=" + list +
", happy=" + happy +
", map=" + map +
", dog=" + dog +
'}';
}
}
至此,项目算是搭建完毕,其最终项目结构为:
3.接下来,我们到了给配置文赋值的时候了。首先来看第一种,即采用最简单的@Value()来赋值。如直接在Dog.java中为Dog赋值:
之后,在测试类中完善代码,即可启动测试:
启动测试类,等待程序运行。发现程序运行成功,显示我们赋予给的值。
尽管此种方法也能成功运行,但是这一般只适用于对象的属性较少的情况,比如我们使用的Dog及只有两个属性,这种情况下我们可以挨个给每个属性使用@Value()方法来赋值,但是当遇到属性较多的情况,比如我们的Person,此时如果继续使用@Value()方法的话,显然很费时间,那么此时第二种方法yaml就该派上用场了。
如果我们能够直接右边的这些值赋给左边的各个属性,那Person的对象就有值了,也就不用去new、去set()了。在实体类上写上@ConfigurationProperties(prefix = "person")
启动测试类,运行成功。
需要注意的是,为了避免报错,在Dog中我们定义了name,那么在Person中,我们最好不要再定义name了,便于区分,不然系统会报装载失败等错误。
那么,第三种方法呢?如果不使用yaml我们又该如何处理呢?此时我们使用指定配置文件方法,即@PropertySourde()方法。前面我们说过,springboot的配置文件是有具体的明明要求的,我们不能随意更改,但是如果我们还是想要使用我们自己命名的配置文件的时候,就可使用此种方法。
例:我们新建一个myself.properties文件。里面内容为自己配置的信息。此时,在java文件中就不能像yaml那样一次性装配了,需要逐个装配。
至此,三种给配置文件赋值的方法已经介绍完毕了。
接下来我们搞一些有趣的东西。还是使用yaml第二种方法。
我们发现,以上三种方法中,当使用@Value()方法时,特别的不方便,其实@Value()方法与@ConfigurationProperties()方法相比有太多的缺点:
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 逐个指定 |
松散绑定 | 支持 | 不支持 |
SPEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
功能:关于@ConfigurationProperties和@Value的功能的不同,我们在上面的程序中已经看到了。
松散绑定:比如java文件中的firstName和配置文件中的first-name,其实是等价的,因为配置文件中“-”之后默认为大写字母。
JSR303数据校验:其实就是在字段上加一层过滤器验证,保证数据的合法性。如,我们再给person一个新的属性email。
运行肯定会报错,显示数据格式错误之类的提示,但是本人电脑报错是装载失败,不知道如何解决~以下是关于JSR303校验的一些内容:
空检查 | |
@Null | 验证对象是否为null |
@NotNull | 验证对象是否不为null,无法检查长度为0的字符串 |
@NotBlank | 检查约束字符串是不是null,还有被Trim的长度是否大于0,只针对字符串,且会去掉前后空格 |
@NotEmpty | 检查约束元素是否为null或empty |
真假检查 | |
@AssertTrue | 验证Boolean对象是否为true |
@AssertFalse | 验证Boolean对象是否为false |
布尔检查 | |
@Size(min=,max=) | 验证对象(包括数组,集合,map等)的长度是否在给定的范围之内 |
@Length(min=,max=) | 验证对象的大小是否在给定范围内 |
日期检查 | |
@Past | 验证Date和Calendar对象是否在当前时间之前 |
@Future | 验证Date和Calendar对象是否在当前时间之后 |
@Pattern | 验证String对象是否符合正则表达式的规则 |
数值检查(建议使用String和Integ类型) | |
@Min | 验证Number和String对象是否大于等于指定的值 |
@Max | 验证Number和String对象是否小于等于指定的值 |
@DecimalMax | 被标注的值必须不大于约束中指定的最大值。这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示,小数存在精度 |
@DecimalMin | 被标注的值必须不小于约束中指定的最大值。这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示,小数存在精度 |
@Digits | 验证Number和String的构成是否合法 |
@Digits(integer=,fraction=) | 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度 |
@Range(min=,max) | 检查数字是否介于Min和Max之间 |
@Valid | 对递归的关联对象进行校验,如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的部分值进行校验 |
@CreditCardNumber | 信用卡验证 |
email邮箱验证 | |
@ScriptAssert(lang=,script=,alias=) | |
@URL(protocol=,host=,port=,regexp=,flags=) |
|
总结一下,什么时候该使用@ConfigurationProperties,什么时候使用@Value:
同时配置了yaml和properties都可以取到值时,强烈推荐yaml;
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用@Value;
如果我们专门编写了一个JavaBean来和配置文件进行映射,就毫不犹豫的直接使用@ConfigurationProperties。