Yaml语法学习
SpringBoot
使用一个全局的配置文件 , 配置文件名称是固定的
application.properties
语法结构 :
key=value
application.yml
语法结构 :
key
:空格
value
YAML
是
"YAML Ain't a Markup Language"
(
YAML
不是一种标记语言)的递归缩写。
在开发的这种语言时,
YAML
的意思其实是:
"Yet Another Markup Language"
(仍是一种标记语言)
这种语言以数据做为中心,而不是以标记语言为重点!
yaml
配置:
server:
prot: 8080
yml
基础语法
说明:语法要求严格!
1
、空格不能省略
2
、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3
、属性和值的大小写都是十分敏感的。
字面量:普通的值
[
数字,布尔值,字符串
]
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
注意:
“ ”
双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
''
单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
对象、
Map
(键值对)
数组(
List
、
set
)
用
-
值表示数组中的一个元素
,
比如:
注入配置文件
yaml
文件更强大的地方在于,他可以给我们的实体类直接注入匹配值
编写一个复杂一点的实体类:Person 类
@Component //注册bean到容器中
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
//有参无参构造、get、set方法、toString()方法
}
编写ymal文件
person:
name: cq
age: 3
happy: false
birth: 2000/01/01
maps: {k1: v1,k2: v2}
lists:
- code
- girl
- music
dog:
name: 旺财
age: 1
注入到我们的类
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/
@Component //注册bean
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
加载指定配置文件
@PropertySource
:
加载指定的配置文件;
@configurationProperties
:默认从全局配置文件中获取值;
@PropertySource(value = "classpath:person.properties")
@Component //注册bean
public class Person {
@Value("${name}")
private String name;
......
}
对比小结
1
、
@ConfigurationProperties
只需要写一次即可 ,
@Value
则需要每个字段都添加
2
、松散绑定:这个什么意思呢
?
比如我的
yml
中写的
last-name
,这个和
lastName
是一样的,
-
后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3
、
JSR303
数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
4
、复杂类型封装,
yml
中可以封装对象 , 使用
value
就不支持
结论:
配置
yml
和配置
properties
都可以获取到值 , 强烈推荐
yml
;
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下
@value
;
如果说,我们专门编写了一个
JavaBean
来和配置文件进行一一映射,就直接
@configurationProperties
,不要犹豫!
多环境切换
profifile
是
Spring
对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;
我们在主配置文件编写的时候,文件名可以是
application-{profifile}.properties/yml ,
用来指定多个环境版本;
例如:
application-test.properties
代表测试环境配置
application-dev.properties
代表开发环境配置
但是
Springboot
并不会直接启动这些配置文件,它
默认使用
application.properties
主配置文件
;
我们需要通过一个配置来选择需要激活的环境:
#
比如在配置文件中指定使用
dev
环境,我们可以通过设置不同的端口号进行测试;
#
我们启动
SpringBoot
,就可以看到已经切换到
dev
下的配置了;
spring.profiles.active
=
dev
yml的多文档块
和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !
注意:如果
yml
和
properties
同时都配置了端口,并且没有激活其他环境 , 默认会使用
properties
配
置文件的!
配置文件加载位置
外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!
springboot
启动会扫描以下位置的
application.properties
或者
application.yml
文件作为
Spring boot
的默认配置文件
优先级
1
:项目路径下的
config
文件夹配置文件
优先级
2
:项目路径下配置文件
优先级
3
:资源路径下的
config
文件夹配置文件
优先级
4
:资源路径下配置文件
优先级由高到底,高优先级的配置会覆盖低优先级的配置
自动配置原理
分析自动配置原理
我们以
HttpEncodingAutoConfifiguration
(
Http
编码自动配置)
为例解释自动配置原理;
//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration
//启动指定类的ConfigurationProperties功能;
//进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
//并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class})
//Spring底层@Conditional注解
//根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
//这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(
type = Type.SERVLET
)
//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({CharacterEncodingFilter.class})
//判断配置文件中是否存在某个配置:spring.http.encoding.enabled;
//如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
//他已经和SpringBoot的配置文件映射了
private final Encoding properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
//给容器中添加一个组件,这个组件的某些值需要从properties中获取
@Bean
@ConditionalOnMissingBean //判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new
OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframew
ork.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframe
work.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
}
//。。。。。。。
}
一句话总结 : 根据当前不同的条件判断,决定这个配置类是否生效!
一但这个配置类生效;这个配置类就会给容器中添加各种组件;
这些组件的属性是从对应的
properties
类中获取的,这些类里面的每一个属性又是和配置文件绑定
的;
所有在配置文件中能配置的属性都是在
xxxxProperties
类中封装着;
配置文件能配置什么就可以参照某个功能对应的这个属性类
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {
// .....
}
精髓
1
、
SpringBoot
启动会加载大量的自动配置类
2
、我们看我们需要的功能有没有在
SpringBoot
默认写好的自动配置类当中;
3
、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4
、给容器中自动配置类添加组件的时候,会从
properties
类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfifigurartion
:自动配置类;
给容器
xxxProperties:
封装配置文件中相关属性;
了解:
@Conditional
了解完自动装配的原理后,我们来关注一个细节问题,
自动配置类必须在一定的条件下才能生效;
@Conditional
派生注解(
Spring
注解版原生的
@Conditional
作用)
作用:必须是
@Conditional
指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;