一、配置文件
Springboot不同于Spring,其配置文件有严格要求:
- application.properties
- application.yml(yaml)
只能是这两种才可以,名称固定。
一般来说Springboot在底层已经配置好,如果需要自己进行配置,便可以通过这个配置文件修改
例如:
1 | server: |
二、YAML语法
2.1.基本语法
yaml由键值对组成,k: v(注意冒号后要跟一个空格)
yaml对空格敏感,对于层级的控制也是由空格来判断的,空格对齐的数据是在一个层级
1 | server: |
上面的例子,即port与path在一个层级,test与name在第三层级。
并且大小写敏感
2.2.值的写法
键值对
由k: v组成,一般来说v不需要加引号
如果加双引号,特殊字符会被转义,如”\n”就会换行
如果加单引号,特殊字符不会被转义
对象、Map
k: v:在下一行来写对象的属性和值的关系;注意缩进
对象还是k: v的方式
1 | friends: |
行内写法:
1 | friends: {lastName: zhangsan,age: 18} |
数组
用- 值表示数组中的一个元素
1 | pets: |
行内写法
1 | pets: [cat,dog,pig] |
三、配置文件注入
比如我们写一个实体类Person与Dog
1 | /** |
application.yml:
1 | person: |
3.1.@ConfigurationProperties注入
由上面代码可以看出来,注入非常简单
1)在pom中添加springboot文件处理器
1 | <!-- 导入配置文件处理器 --> |
2)在需要注入的类中添加两个注解,并设置属性
1 |
|
注意配置文件使用的是application.yaml
3.2.@Value注入
properties之前经常用到,比较熟悉,比如配置数据库信息等等,因为上面我们使用了yml注入,所以这次我们注入properties,两者都是一样使用的
1 | zhangsan = |
在需要注入的字段上加@Value注解
1 | public class Person { |
3.3.两者区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL(如#{11*2}) | 不支持 | 支持 |
数据校验(@Validated) | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
配置文件yml还是properties他们都能获取到值;两者使用场景:
我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
我们专门编写了一个javaBean来和配置文件进行映射,使用@ConfigurationProperties。
3.4.数据校验
对于配置文件注入时,只有@ConfigurationProperties注解可以配合使用数据校验@Validated,@Value不可用使用。
1 |
|
因为birth给定的是日期类型,所以启动会报错,即数据校验成功
一些常用的数据校验注解:
限制 | 说明 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@AssertFalse | 限制必须为false |
@AssertTrue | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Past | 限制必须是一个过去的日期 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 |
3.5.指定配置文件
3.5.1.@PropertySource
一般情况下,配置文件使用默认的application.yml或者application.properties,如果想要修改,就需要使用注解@PropertySource,加载指定配置文件
1 | "classpath:person.properties"}) (value = { |
注意!!!
使用指定配置文件时,需要把application中的相同配置注释掉,不然还是使用的application中的
3.5.2.@ImportResource
使用这个注解一般用来加载xml配置文件,比如Spring的配置文件
1 |
|
导入Spring的配置文件让其生效
1 | @SpringBootApplication |
测试查看:
正确加载到容器中。
3.5.4.注解添加组件
注意,这是使用配置文件xml来进行对容器添加组件,Springboot提倡全注解开发,所以不建议使用xml来添加,他推荐了一种方法来配置:
1)创建一个配置类,相当于配置文件
2)使用@Bean注解进行添加
1 |
|
3.5.4.总结
对于Springboot加载指定配置文件,有以下总结
- 使用@PropertySource来加载properties或yaml文件
- 使用@ImportResource加载xml文件(不推荐使用)
- 使用@Configuration配合@Bean来添加组件,而不是使用spring的xml文件注入bean
四、占位符
配置文件中也可以有占位符,使用${}
的格式
可以是自带的随机函数,也可以是上面定义的参数,也可以是没定义的参数使用:
来指定
1 | #使用随机函数random |
五、Profile
当应用需要部署开发环境或生产环境时,便需要不同的配置文件,有两种方式
5.1.多properties
编写多个application文件,命名为application-xxx.properties
然后再主文件中配置使用哪个环境的配置文件,例如:
1 | dev = |
即使用application-dev.properties
5.2.yml配置
在使用yaml配置多环境时,便不需要写多个yml文件了,他有文件块机制
1 | server: |
5.3.激活指定profile
1)在配置文件中激活
properties:
1 | dev = |
yml:
1 | spring: |
2)在启动时添加参数
运行jar时:
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
3)虚拟机参数
-Dspring.profiles.active=dev
六、配置文件加载位置
SpringBoot如果有重复的配置文件在不同的位置,其优先级也会不同
对于不同位置的配置文件,有一个互补原则,没有的配置会聚合,相同的配置被覆盖
我们还可以通过spring.config.location来改变默认的配置文件位置
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;
java -jar spring-boot-02-config.jar --spring.config.location=G:/application.properties
七、Springboot的自动配置原理
当我们在application.yml
配置时,是这样配的
1 | server: |
可以发现,我们在配置文件中配置spring.http.encoding.charset
,其应用便会自动的帮我们设置好骑编码为utf-8,那么他的原理是什么呢?我们探究一下
在上一篇笔记中,我们讲到Springboot的最重要注解@SpringBootApplication
- @SpringBootApplication中具有一个@EnableAutoConfiguration注解
- 在里面Import了一个
EnableAutoConfigurationImportSelector
类 - 其中有一个
getCandidateConfigurations
方法,调用了Loader
的loadFactoryNames
方法 - 这个方法是根据
META-INF/spring.factories
中配置的AutoConfiguration
类进行装载到容器中
而我们在配置文件中的配置,全部都来自于这些AutoConfiguration类!
我们拿HttpEncodingAutoConfiguration来举例:
1 |
|
- @Configuration:代表他是一个配置类
- @EnableConfigurationProperties(HttpEncodingProperties.class):启动指定类的
ConfigurationProperties
功能,即将配置文件中的值与HttpEncodingProperties
这个类绑定起来 - @ConditionalOnWebApplication:判断是否是web项目,如果不是便配置不生效
- @ConditionalOnClass(CharacterEncodingFilter.class):判断是否编写了
CharacterEncodingFilter
这个过滤器,如果已经编写了,便不会生效了,使用用户自己编写的过滤器 - @ConditionalOnProperty(prefix = “spring.http.encoding”, value = “enabled”, matchIfMissing = true):判断
application.yml
配置文件里是否写了spring.http.encoding
这个值,如果为enabled
或者没有写,即生效,如果为disable
便不生效
再进入HttpEncodingProperties看一下
可以发现,获取的便是我们配置文件中的spring.http.encoding
的属性,而字段charset
就是对应的值
总结
- SpringBoot启动时会加载大量自动配置类
- 我们根据需要在配置文件中配置
- 自动配置类会根据一些@Conditional判断是否生效这些配置,如果生效
- Springboot会自动将我们配置的值装载到类中,生成一些所需的组件,比如HttpEncodingAutoConfiguration就会生成一个CharacterEncodingFilter过滤器,来帮我们处理编码问题
- 主要的文件是:
- xxxxAutoConfigurartion:自动配置类,给容器添加组件
- xxxxProperties:封装配置文件中的值,
@Conditional
可以发现,我们每个自动配置类中都有很多的conditional,这个是Spring底层的一个注解,用来判断条件是否成立,如果成立了,才会向容器中添加组件
SpringBoot自带了很多自动配置类,但不是全部生效的,就是因为@Conditional的作用
我们可以在配置文件中通过启用debug: true
属性来让控制台打印哪些自动配置类生效了:
生效的类:
未生效的类: