SpringBoot③YAML和JSR-303
4、YAML
4.1、SpringBoot配置文件
为什么需要配置文件
- Spring Boot 默认实现了很多自动配置。
- 当我们不想用默认配置时,可以通过配置文件来自定义配置。
- 约定大于配置:开发人员仅需规定不符合规定的部分,没有规定配置的地方采用默认配置,以达到最简配置。
Spring Boot 配置文件
Spring Boot 使用全局的配置文件,文件名称为application(这个名称是固定的)。
-
application.properties
-
语法:
Key=Value
-
例如:
server.port=8081
-
-
application.yaml(官方建议使用
.yaml
扩展名,尽量不要用.yml
扩展名)-
语法:
Key:空格Value
-
例如:
server port: 8081
-
4.2、YAML
4.3、注入YAML配置文件
4.3.1、Spring注入
学习 YAML 配置注入之前,先思考一下 Spring 常用的三种注入方式
环境搭建
对
基于注解的自动注入
进行测试。
-
在主程序的同级目录下,新建 pojo 包;
-
在包中新建一个 pet 类,使用
@Value
注入属性值:@Component public class Pet { @Value("小七") private String name; @Value("3") private Integer age; @Override public String toString() { return "Pet{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
测试
@SpringBootTest
public class PetTest {
/**
* 自动注入pet
*/
@Autowired
Pet pet;
@Test
public void test() {
System.out.println(pet);
}
}
下面编写一个复杂的实体类,来对 YAML 配置注入进行测试。
4.3.2、YAML注入
- 编写
application.yaml
配置文件,使用@ConfigurationProperties
引入 - 通过 setter 方式自动注入,要求实体类具有 setter
环境搭建
编写一个复杂的实体类,测试 YAML 注入属性
-
在 pojo 包中创建 Person 类
@Component public class Person { private String name; private Integer age; private Boolean gender; private Date birthday; private List<String> list; private Map<String, Object> map; private Pet pet; // 每个属性的setter @Override public String toString() { return "Person{" + "\n" + " name='" + name + '\'' + "\n" + " age=" + age + "\n" + " gender=" + gender + "\n" + " birthday=" + birthday + "\n" + " list=" + list + "\n" + " map=" + map + "\n" + " pet=" + pet + "\n" + '}'; } }
-
编写 YAML 配置文件:
application.yaml
- 配置与实体类的属性一一对应;
- 注意空格
person: name: jaywee age: 7 gender: true birthday: 2007 list: - java - spring map: k1: v1 k2: v2 pet: name: 小七 age: 3
-
在 Person 类中引入 YAML 配置文件
-
使用注解:
@ConfigurationProperties(prefix="xx")
; -
prefix 的值与 YAML 文件中最左边的配置对应
@ConfigurationProperties(prefix = "person") @Component public class Person { ... }
-
测试
- 输出的属性为 null,可能是以下原因:
- 实体类的属性名和 YAML 文件不一致;
- 实体类没有 setter 方法;
- 报错:
Failed to convert from type [java.lang.String] to type [java.util.Date] for value 'xxx'
- 原因:YAML 文件的日期格式错误,必须是
xxxx/xx/xx
格式
@SpringBootTest
public class PersonTest {
/**
* 自动注入person
*/
@Autowired
Person person;
@Test
void test() {
System.out.println(person);
}
}
关于 Spring Boot Configuration Annotation Processor 的说明
-
部署 Spring Boot 配置文件时,IntelliJ IDEA 会报红:
Spring Boot Configuration Annotation Processor not configured
(Spring Boot 配置注解处理器没有配置)- 不影响运行
-
Spring Boot 配置注解处理器:
-
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
-
配置该处理器之后,实体类的字段与 YAML 配置之间有可视化的映射关系;
-
4.3.3、指定配置文件注入
- 自定义
.properties
配置文件,使用@PropertiesSource
引入 - 使用
@Value(${xxx})
注入
测试
对 person 类的部分属性注入进行测试
-
在 resources 目录下编写配置文件
name=SecretMrJ age=7 gender=true
-
在 Person 类中引入配置文件
@PropertySource("classpath:jaywee.properties") @Component public class Person { @Value("${name}") private String name; @Value("${age}") private Integer age; @Value("${gender}") private Boolean gender; ... }
-
测试:注入成功
4.3.4、小结
常用注入方式
Spring 阶段
- 构造器注入、setter 注入:在 Spring 中常用,通过 XML 配置实现;
- 基于注解的自动注入:使用 @Value 等注解进行注入;
Spring Boot 阶段
- YAML 注入:Spring 官方推荐,通过 @ConfigurationProperties 引入配置文件!
- 指定配置文件注入:通过 @PropertySource 引入配置文件,使用 @Value 注解。
YAML 注入 vs 指定配置文件注入
YAML注入 | 指定配置文件注入 | |
---|---|---|
配置文件 | application.yaml | 自定义配置文件 |
引入方式 | @ConfigurationProperties 默认从全局配置文件中获取值 |
@PropertiesSource 加载指定的配置文件 |
注入方式 | 自动将属性批量注入 | @Value 为每个属性注入 |
功能支持 | 松散绑定、JSR303 数据校验、复杂类型封装 | SpEL |
功能说明
功能 | 说明 |
---|---|
松散绑定 | 属性的驼峰式、下划线、短横线,不同命名方式之间可以绑定。 如:first_name 可以与 firstName 对应并绑定。 |
JSR303 数据校验 | 在属性上增加一层过滤器验证,保证数据的合法性 |
复杂类型封装 | YAML 文件中支持封装对象 |
SpEL | 即 Spring Expression Language(Spring 表达式语言),比 JSP 的 EL 表达式更强大 |
结论
一般情况下推荐使用 YAML
- 只需要获取配置文件中的某个值,使用
@Value
; - 需要批量获取配置文件中的值,使用
@ConfigurationProperties
注入 YAML 配置文件- 如:编写 JavaBean 与配置文件一一映射。
4.4、拓展:JSR303数据校验
JSR(Java Specification Requests):Java 规范提案
- 指的是向 JCP(Java Community Process)提出新增一个标准化技术规范的正式请求;
- 任何人都可以提交 JSR,以向 Java 平台增添新的 API 和服务;
- JSR 已成为 Java 界的一个重要标准。
JSR-303 是 JAVA EE 6 中的一项子规范,叫做Bean Validation。
-
在 Spring Boot 中,可以使用注解 @Validated 来校验数据;
-
如果数据异常则会统一抛出,方便异常的中心统一处理;
-
使用方式
-
导入 starter 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
-
在类上方:使用注解 @Validated
-
在属性上方:使用相应功能的注解
-
下面搭建一个环境,来对 JSR-303 进行测试。
4.4.1、创建 Employee 类
创建 Employee 类,使用 JSR
@Component
@ConfigurationProperties(prefix = "employee")
@Validated
public class Employee {
@NotNull
private String name;
@Max(100)
private int age;
@Email
private String email;
// setter、toString()
}
4.4.2、编写 YAML 配置
employee:
name: jaywee
age: 7
email: jaywee7@126.com
4.4.3、测试
测试类
@SpringBootTest
public class EmployeeTest {
@Autowired
private Employee employee;
@Test
void test() {
System.out.println(employee);
}
}
测试结果
进一步测试
- 修改 YAML 配置进行测试,查看报错结果
- 去掉 name(此时 name 为空)
codes [employee.name,name]; arguments []; default message [name]]; default message [不能为null]
- age 改为101(此时 age 超过最大值100)
codes [employee.age,age]; arguments []; default message [age],100]; default message [最大不能超过100]
- 邮箱改为 jaywee777(此时 email 不是邮箱格式)
default message [不是一个合法的电子邮件地址]
- 去掉 name(此时 name 为空)