4.SpringBoot配置
4.1 创建一个SpringBoot项目
4.1.1 选择Spring initializer项目
4.1.2 项目创建成功
springboot 这个配置文件中到底可配置哪些东西呢?
官方的配置太多了,因此只有了解原理:才能一通百通
4.1.3 修改配置文件
1.创建application.yml配置文件
- 首先删除application.properties配置文件,然后创建一个application.yml配置文件
2.编写application.yml配置文件信息
# 设置服务器端口
server:
# 注意port和8888之间有空格,去掉空格就没有高亮提示了
port: 8888
4.2 YAML配置文件的使用
4.2.1 配置文件
SpringBoot使用一个全局的配置文件,配置文件名称是固定的
- application.properties
语法结构:key=value - application.yml
语法结构:key: 空格 value
配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动装配好了
4.2.2 YAML
1.什么是YAML?
YAML是YAML Ain·t a Markup Language" (即YAML不是一种置标语言) 的递归缩写
在开发这种语言时,YAML的意思是:“Yet Another Markup Language” (仍是一种置标语)
YAML A Markup Language:是一个标记语言
YAML isnot Markup Language:不是一个标记语言
2.标记语言
以前的配置文件,大多数都是使用xml配置,比如一个简单的端口配置,我们来对比一下yaml和xml
- 使用yaml配置:
# 设置服务器端口
server:
# 注意port和8888之间有空格,去掉空格就没有高亮提示了
port: 8888
- 使用xml配置:
# 设置服务器端口号
<server>
<port>8888</port>
</server>
3.YAML语法
- 使用yml配置文件
# k-v
# 对空格的要求十分高!
# 普通的key-value
name: zhangsan
# 对象
student:
name: zhangsan
age: 22
# 行内写法, 注意: teacher和{}之间有空格
teacher: {name: luoxiang,age: 33}
# 数组
# 使用"-"",注意"-"和"zhangsan"之间有空格
students:
- zhangsan
- lisi
- wanger
# 使用"[]"
teachers: [luoxiang,kuangshen,banfo]
- 使用properties配置文件
#yml和properties配置文件都会起作用
# 属性
name=zhangsan
# 对象
student.name = zhangsan
student.age = 22
4.2.3 使用yaml配置文件给实体类赋值
1.编写Dog实体类
1-1 使用常规形式
package com.kuang.pojo;
@Component //使用@Component注册bean到Spring容器中去
public class Dog {
@Value("旺财")
private String name;
@Value("3")
private String age;
//无参构造
public Dog() {
}
//有参构造
public Dog(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
//toString方法
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
1-2 使用注解形式
- 引入lombok资源依赖
<!--lombok资源依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
- 引入基本注解
package com.kuang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component //使用@Component注册bean到到Spring容器中去
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
public class Dog {
@Value("旺财")
private String name;
@Value("3")
private String age;
}
2.编写Person类
2-1 使用常规方式
- 使用@ConfigurationProperties注解绑定配置文件相关属性
package com.kuang.pojo;
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//使用@Component添加组件(注册bean)到Spring容器中去
/*
使用@ConfigurationProperties注解作用:
将配置文件中配置的每一个属性的值,映射到这个组件中
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
如果不配置使用该注解,就会报红,但并不会影响运行结果
只有当这个组件是容器中的组件时,才能使用容器提供的@ConfigurationProperties(功能*/
//使用@ConfigurationProperties注解与yaml配置文件进行绑定
@ConfigurationProperties(prefix = "person")
//参数prefix = "person":将配置文件中的person下面的所有属性一一对应
public class Person {
private String name; //姓名
private Integer age; //年龄
private Boolean ishappy; //是否开心
private Date birthday; // 生日
private Map<String,Object> maps; //证件
private List<Object> lists; //爱好
private Dog dog; //宠物狗
//无参构造
public Person() {
}
//有参构造
public Person(String name, Integer age, Boolean ishappy, Date birthday, Map<String, Object> maps, List<Object> lists, Dog dog) {
this.name = name;
this.age = age;
this.ishappy = ishappy;
this.birthday = birthday;
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 getIshappy() {
return ishappy;
}
public void setIshappy(Boolean ishappy) {
this.ishappy = ishappy;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
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 +
", ishappy=" + ishappy +
", birthday=" + birthday +
", maps=" + maps +
", lists=" + lists +
", dog=" + dog +
'}';
}
}
- 解决使用@ConfigurationProperties注解的爆红问题
<!--解决使用@ConfigurationProperties注解的爆红问题-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2-2 使用注解形式
package com.kuang.pojo;
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
@Component//使用@Component添加组件(注册bean)到Spring容器中去
//使用@ConfigurationProperties注解与yaml配置文件进行绑定
@ConfigurationProperties(prefix = "person")
//参数prefix = "person":将配置文件中的person下面的所有属性一一对应
public class Person {
private String name; //姓名
private Integer age; //年龄
private Boolean ishappy; //是否开心
private Date birthday; // 生日
private Map<String,Object> maps; //证件
private List<Object> lists; //爱好
private Dog dog; //宠物狗
}
3. 编写application.yml配置文件
3-1 复杂形式
person:
name: zhangchulan
age: 22
ishappy: false
birthday: 1999/06/08
maps:
k1: v1
k2: v2
lists:
- programming
- music
- games
dog:
name: 旺财
age: 3
3-2 简单形式
person:
name: zhangchulan
age: 22
ishappy: false
birthday: 1999/06/08
maps: {k1: v1,k2: v2}
lists: [programming,music,games]
dog: {name: 旺财,age: 3}
4. 编写测试类
4-1 自动装配Dog类
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired //通过类型或名字进行自动装配
// @Qualifier(value= "dog")
private Dog dog;
@Test
void contextLoads() {
System.out.println(dog);
}
}
4-2 自动装配Person类
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired //进行自动装配
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
5.测试结果
5-1 自动装配Dog类
5-2 自动装配Person类
4.2.4 使用properties配置文件
上面采用的是最简单也是最常用的方式,当然也可以通过配置properties文件来实现
1.设置UTF-8的编码格式
注意:在properties配置文件中写中文时,会有乱码,因此需要去IDEA中设置编码格式为UTF-8
2.修改Person实体类
package com.kuang.pojo;
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
@Component//使用@Component添加组件(注册bean)到Spring容器中去
//JavaConfig绑定配置文件的值,可以采用这些方式!
//使用@PropertySource注解,加载指定的配置文件
@PropertySource(value= "classpath:application02.properties")
public class Person {
//使用SPEL表达式取出配置文件的值
@Value("${name}")
private String name; //姓名
private Integer age; //年龄
private Boolean ishappy; //是否开心
private Date birthday; // 生日
private Map<String,Object> maps; //证件
private List<Object> lists; //爱好
private Dog dog; //宠物狗
}
3.创建application02.properties
name=zhangchulan
4.编写测试类
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired //进行自动装配
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
5.测试结果
4.2.5 在yml配置文件中使用spel表达式
1.修改Person实体类
package com.kuang.pojo;
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
@Component//使用@Component添加组件(注册bean)到Spring容器中去
@ConfigurationProperties(prefix = "person")
//参数prefix = "person":将配置文件中的person下面的所有属性一一对应
public class Person {
private String name; //姓名
private Integer age; //年龄
private Boolean ishappy; //是否开心
private Date birthday; // 生日
private Map<String,Object> maps; //证件
private List<Object> lists; //爱好
private Dog dog; //宠物狗
}
2.修改application.yml配置文件
2-1 使用时指定hello的值
person:
name: zhangchulan${random.uuid}
age: ${random.int}
ishappy: false
birthday: 1999/06/08
maps: {k1: v1,k2: v2}
lists: [programming,music,games]
# 注意:这个dog要跟前面的属性对齐写,不能顶格写
# _表示占位符,拼接_后面的值
dog:
name: ${person.hello:hello}_旺财
age: 3
2-2 预先指定hello的值
person:
name: zhangchulan${random.uuid}
age: ${random.int}
ishappy: false
birthday: 1999/06/08
maps: {k1: v1,k2: v2}
hello: happy
lists: [programming,music,games]
dog:
name: ${person.hello}_旺财
age: 3
3.编写测试类
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired //进行自动装配
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
4.修改编码格式
如果出现编译失败的情况,要修改编码格式为UTF-8
5.测试结果
5-1 使用时指定hello的值
Person(name=zhangchulan4ab5c207-3889-4c30-822f-84faf2266151, age=-474299478, ishappy=false, birthday=Tue Jun 08 00:00:00 CST 1999, maps={k1=v1, k2=v2}, lists=[programming, music, games], dog=Dog(name=hello_旺财, age=3))
5-2 预先指定hello的值
Person(name=zhangchulan99d06de4-8de1-4f94-b326-01b052078be1, age=-1357082319, ishappy=false, birthday=Tue Jun 08 00:00:00 CST 1999, maps={k1=v1, k2=v2}, lists=[programming, music, games], dog=Dog(name=happy_旺财, age=3))
4.2.6 @ConfigurationProperties注解和@Value注解的区别
@ConfigurationProperties | @Value | |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
- @ConfigurationProperties只需写一次即可,@Value则需要每个字段都添加
- 松散绑定:例如yml配置文件中写的“last-name“,这个和“lastName"是一样的,"-"后面跟着的字母默认是大写的,这就是松散绑定
- JSR303数据校验:这个就是我们可以字段是增加一层过滤验证,可以保证数据的合法性
- 复杂类型封装:yml中可以封装对象,使用@Value就不支持
4.2.7 松散绑定的使用
1.修改Dog和Person实体类
1-1 修改Dog实体类
package com.kuang.pojo;
@Component //使用@Component注册bean到到Spring容器中去
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
//使用@ConfigurationProperties注解与yml配置文件绑定
@ConfigurationProperties(prefix = "dog")
//prefix = "dog":与yml配置文件中dog的所有属性一一对应
public class Dog {
private String FirstName;
private String age;
}
1-2 修改Person实体类
package com.kuang.pojo;
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
@Component//使用@Component添加组件(注册bean)到Spring容器中去
//使用@ConfigurationProperties注解与yaml配置文件进行绑定
@ConfigurationProperties(prefix = "person")
//参数prefix = "person":将配置文件中的person下面的所有属性一一对应
public class Person {
//使用SPEL表达式取出配置文件的值
// @Value("${name}")
private String lastName; //姓名
// private String latsName; //姓名
private Integer age; //年龄
private Boolean ishappy; //是否开心
private Date birthday; // 生日
private Map<String,Object> maps; //证件
private List<Object> lists; //爱好
private Dog dog; //宠物狗
}
2.修改application.yml配置文件
2-1 设置dog的所有属性
dog:
first-name: 大黄
age: 5
2-2 设置person的所有属性
person:
last-name: chulan
age: ${random.int}
ishappy: false
birthday: 1999/06/08
maps: {k1: v1,k2: v2}
hello: happy
lists: [programming,music,games]
dog:
first-name: ${person.hello}_旺财
age: 3
3.修改测试类
package com.kuang;
import com.kuang.pojo.Dog;
import com.kuang.pojo.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired //通过类型或名字进行自动装配
private Dog dog;
@Autowired //进行自动装配
private Person person;
@Test
void contextLoads() {
//打印dog和person信息
System.out.println(dog);
System.out.println(person);
}
}
4.测试结果
4-1 注入dog对象
4-2 注入person对象
Person(lastName=chulan, age=-1816134270, ishappy=false, birthday=Tue Jun 08 00:00:00 CST 1999, maps={k1=v1, k2=v2}, lists=[programming, music, games], dog=Dog(FirstName=happy_旺财, age=3))
4.2.8 使用结论
- 配置yml和properties文件都可以获取到值,强烈推荐yml配置文件
- 如果在某个业务中,只需要获取文件中的某个值,可以使用一下@Value
- 如果专门编写了一个JavaBean来和配置文件进行映射,就直接使用@ConfigurationProperties
4.2.9 JSR303校验
SpringBoot中可以使用@Validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理
1.修改Perosn实体类
- 让我们来写个注解让Person实体类的name属性只能支持Email格式
package com.kuang.pojo;
@Data //引入无参构造,get和set方法,toString方法
@AllArgsConstructor //引入有参构造
@NoArgsConstructor//引入无参构造,防止引入有参构造时覆盖掉无参构造
@Component//使用@Component添加组件(注册bean)到Spring容器中去
//JavaConfig绑定配置文件的值,可以采用这些方式!
//使用@ConfigurationProperties注解与yaml配置文件进行绑定
@ConfigurationProperties(prefix = "person")
//参数prefix = "person":将配置文件中的person下面的所有属性一一对应
@Validated //数据校验
public class Person {
//该属性必须符合Email格式,可以使用message来自定义报错信息
@Email(message = "邮箱格式错误!")
private String name; //姓名
private Integer age; //年龄
private Boolean ishappy; //是否开心
private Date birthday; // 生日
private Map<String,Object> maps; //证件
private List<Object> lists; //爱好
private Dog dog; //宠物狗
}
2.修改application.yml配置文件
person:
name: zhangchulan
age: ${random.int}
ishappy: false
birthday: 1999/06/08
maps: {k1: v1,k2: v2}
hello: happy
lists: [programming,music,games]
dog:
first-name: ${person.hello}_旺财
age: 3
3.修改测试类
package com.kuang;
import com.kuang.pojo.Dog;
import com.kuang.pojo.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Springboot02ConfigApplicationTests {
@Autowired //进行自动装配
private Person person;
@Test
void contextLoads() {
//打印person信息
System.out.println(person);
}
}
4.测试结果
结果:由于我们输入的名字是"zhangchulan",所以不符合电子邮箱格式
5.常用的JSR303校验注解
Constraint | 详细信息 |
@Null | 被注释的元素必须为null |
@NotNull | 被注释的元素不为null |
@AssertTrue | 被注释的元素必须为true |
@AssertFalse | 被注释的元素必须为false |
@Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DeciamlMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max,min) | 被注释的元素的大小必须在指定的范围内 |
@Digits(intger,fraction) | 被注释的元素的大小必须是一个数字,其值必须在可接受的范围内 |
@Past | 被注释的元素必须是一个过去的日期 |
@Futrue | 被注释的元素必须是一个将来的日期 |
@Pattern(value) | 被注释的元素必须符合指定的正则表达式 |
@Email | 被注释的元素必须是电子邮箱地址 |
@Length | 被注释的字符串大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串必须非空 |
@Range | 被注释的元素必须在合适的范围内 |
6.JSR303校验常用注解位置