前言:

本文内容:JSR303校验、多环境配置及配置文件位置、自动配置原理再理解

推荐免费SpringBoot基础教程视频:[【狂神说Java】SpringBoot最新教程通俗易懂_哔哩哔哩_bilibili

JSR303校验

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

Email爆红引入这个依赖即可

1
2
3
4
5
<!--        @Validated -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

这里我们让Person实体类的name必须为邮箱格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.jokerdig.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.Email;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
* @author Joker大雄
* @data 2022/7/13 - 11:29
**/
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "person")
@Validated // 数据校验
public class Person {
@Email()
private String name;
private Integer age;
private boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}

运行测试,发现报错(我们赋值不是Email)

1
2
3
4
5
6
7
8
9
-------------------------------------------------------------------------------
Test set: com.jokerdig.Springboot02ConfigApplicationTests
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.736 s <<< FAILURE! - in com.jokerdig.Springboot02ConfigApplicationTests
contextLoads Time elapsed: 0.001 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.boot.context.properties.bind.validation.BindValidationException:
Binding validation errors on person
- Field error in object 'person' on field 'name': rejected value [JokerDaxiong]; codes [Email.person.name,Email.name,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.name,name]; arguments []; default message [name],[Ljavax.validation.constraints.Pattern$Flag;@3af356f,.*]; default message [不是一个合法的电子邮件地址]; origin class path resource [application.yaml]:2:9

除了Email(),JSR303还有一些常用的注解

注解 说明
@Null 必须为null
@NotNull 必须不为null
@AssertTrue 必须为true
@AssertFalse 必须为false
@Min(value) 必须为一个数字,其值必须大于等于指定的最小值
@Max(value) 必须为一个数字,其值必须小于等于指定的最小值
@DecimalMin(value) 必须为一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 必须为一个数字,其值必须小于等于指定的最小值
@Size(max,min) 元素的大小必须在指定范围内
@Digits(int,fraction) 必须是一个数字,其值必须在可接受范围内
@Past 必须是一个过去的日期
@Future 必须是一个将来的日期
@Pattern(value) 其值必须符合指定的正则表达式
@Email 被修饰的元素必须是电子邮件
@Length 被修饰的元素长度必须在指定的范围内
@NotEmpty 被修饰的元素必须非空
@Range 被修饰的元素必须在合适的范围内

多环境配置及配置文件位置

配置文件可以存放的位置

  1. file:./config/根目录的config文件下放置
  2. file:./根目录下放置
  3. classpath:/config/resources目录的config文件下放置
  4. classpath:/resources目录下放置

分别在四个位置新建配置文件,然后设置端口号,运行项目观察默认生效的端口号

1
2022-07-14 10:19:32.371  INFO 12196 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8082 (http) with context path ''

发现执行了8082端口,8082端口是在根目录下的config文件夹下的配置文件

我们运行并删除配置文件,来观察配置文件的优先级,得出:

根目录的config文件下放置的优先级>根目录下放置的优先级>resources目录的config文件下放置的优先级>resources目录下放置的优先级

SpringBoot多环境切换

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

方式一:多配置文件

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

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

但是SpringBoot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;我们需要通过一个配置来选择需要激活的环境;

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

以上properties都可以替换为yaml,这里只是举例

运行测试

启动端口已经切换到dev开发环境

1
Tomcat started on port(s): 8083 (http) with context path ''

方式二:自主选择

yaml提供了多文档模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 方式二 多文档模块
server:
port: 8081

# 激活开发端口
spring:
profiles:
active: dev
---
server:
port: 8082
spring:
profiles: test
---
server:
port: 8083
spring:
profiles: dev

运行测试

1
Tomcat started on port(s): 8083 (http) with context path ''

自动配置原理再理解

自动配置再理解

1
2
3
4
5
6
// spring接管
@Configuration(proxyBeanMethods = false)
// spring中能配置的内容都在这个属性下对应
@EnableConfigurationProperties(WebServicesProperties.class)
// 封装配置文件中相关属性
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)

自动装配总结

  1. SpringBoot启动会加载大量的自动配置类
  2. 观察我们需要的功能有没有在SpringBoot默认写好的自动配置类中
  3. 再来看这个自动配置类中到底配置了哪些组件(如果存在就不需要手动配置了)
  4. 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。只需要再配置中指定这些属性的值即可

核心

  • xxxAutoConfiguration:自动配置类,为容器添加组件

  • xxxProperties:封装配置文件中相关属性

@Conditional

了解自动装配原理,我们发现自动配置类必须在一定条件下才能生效;@Conditional派生注解(Spring原生注解)

作用:必须是@conditional指定条件成立,才能为容器中添加组件,所配置的内容才能生效;

@Conditional注解拓展 作用
@ConditionalOnJava 系统的Java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean
@ConditionalOnMissingBean 容器中不存在指定Bean
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项

如何判断配置类是否生效

1
2
# 开启springboot调试类
debug: true

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

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

Unconditional classes:没有条件的类