博主正在开心的准备看英雄联盟季后赛 FPX和RNG的比赛,这时候女朋友林妹妹走过来
林妹妹:我最近在学习spring,现在学到了数据绑定@Value这个注解,学的不是很明白,你能给我讲讲吗?
博主:等一会哈,我看完比赛
林妹妹:纳尼?
博主:你听错的我时候的马山开始,看什么比赛(害怕中…)
准备好了吧,咱们先从简单类型开始
1、String类型
首先我们创建一个spring boot项目,不会的可以看下博主的另一篇文章idea创建Springboot 2.X项目
然后在application.yaml中配置如下内容
chilx:
person:
name: chilx
age: 18
接着我们就是可以使用这两个参数了
创建个一个Person类,使用就可以使用@Value注解了
@Value("${chilx.person.name}")
private String name;
@Value("${chilx.person.age}")
private Integer age;
林妹妹:好的那我试下
过了一会--------
林妹妹:不对呀我这里项目报错呀
博主:我看看,(瞟了一眼后)你呀你真是个小笨蛋,你看看错误提示,你使用的没有声明的参数
这一点我忘了和你说当我们使用@Value引用没有声明的参数时会报报错的哦
例如 gender 这个属性在配置文件中没有声明,我们在Perso类中添加一下内容
@Value("${chilx.person.gender}")
private String gender;
启动项目会报以下的错误
林妹妹:那有没有解决的方法呀?
当然是有的呀,我们在引用属性的时候可以给一个默认值,当属性不存在的时候就赋值其默认值
我们改造下刚才的内容,在引用参数的后面加上冒号和默认值就可以了
// 默认值为空串
@Value("${chilx.person.gender:}")
private String gender1;
// 默认值为null
@Value("${chilx.person.nikeName:null}")
private String gender2;
// 默认值为 男
@Value("${chilx.person.password:'男'}")
private String gender3;
这个是刚才的问题就迎刃而解了
好了,@Value的基本使用就说完了,你还有什么不明白的吗?
林妹妹:没有了,现在基本的使用我已经明白了
博主:好,那下面我们继续
2、Array类型
接下来我们来看下数组类型
配置文件添加一下配置
chilx:
person:
....
hobbies: 篮球, 足球, 游戏
Person类中添加
@Value("${chilx.person.hobbies}")
private String[] hobbies;
然后就可以了,简单吧
林妹妹:嗯嗯,简单简单,套路我都知道了
博主:看把你厉害的,继续继续
3、List/Set集合类型
接下来我们来学习下集合类型,List和Set使用是一样的,只是Set会去重
继续在application.yaml 中添加配置
chilx:
person:
....
friend: 小明, 小红
林妹妹:我知道一下怎么做了,这不是和Array类型的一样么,谁还不会,不就是在Person类中添加,以下内容不就行了
@Value("${chilx.person.friend}")
private List<String> friend;
得意的启动项目中… 执行成功
怎么样,我厉害吧
博主:厉害厉害,你也知道当属性不存在的时候直接引用属性是会报错的,集合类型你知道怎么
林妹妹:这个,这个不知道耶(小声)
博主:哈哈哈,看你还得嘚瑟不,这下知道自己的不足了吧
林妹妹:哎呀,不要说我了,快给我讲讲怎么处理呀
博主:好的,好的,这就给你说不要打我了,你要好好看看下面的代码, 大致可以分为以下几种情况
// 默认值 []
@Value("${chilx.person.friend1:}")
private List<String> friend1;
// 默认值 [null]
@Value("${chilx.person.friend1:null}")
private List<String> friend2;
// 默认值 [小明,小红]
@Value("${chilx.person.friend1:小明,小红}")
private List<String> friend3;
// 以下是使用的EL表达式
// 默认值 []
@Value("#{'${chilx.person.friend1:}'.split(',')}")
private List<String> friend4;
// 默认值 [null]
@Value("#{'${chilx.person.friend1:null}'.split(',')}")
private List<String> friend5;
// 默认值 [小明,小红]
@Value("#{'${chilx.person.friend1:小明,小红}'.split(',')}")
private List<String> friend6;
// 默认值 []
@Value("#{'${chilx.person.friend1:,}'.split(',')}")
private List<String> friend7;
林妹妹:懂了,懂了原来是这样的。咦,不对呀,Array类型的你怎么没给我讲默认值呀的问题呀
博主:想起来了呀,我以为你忽略了这个问题那
林妹妹:怎么你在怀疑我????
博主:不敢不敢,前面我之所以没说是以为Array,List和Set在默认值方面是一样的,知道了啵
其实集合类型还有其他几种的注入类型的,只是不能使用@Value进行注解
等给你讲完Map类型在给你详细道来
来来咱们继续
4、 Map类型
接下来咱们来说说字典类型哈
林妹妹:(小声道)不都是一样的套路,谁还不知道
博主当做没听到…
首先在配置文件中添加配置
chilx:
person:
.....
pet: "{'小狗':'旺旺', '小猫':'喵喵'}"
courses: "{'语文':100, '数学':99}"
java类中添加对应的属性,注意@Value中要使用EL表达式
@Value("#{${chilx.person.pet}}")
private Map<String, String> pet;
@Value("#{${chilx.person.courses}}")
private Map<String, String> courses;
这样就可以了是不是很简单
林妹妹:嗯呐
同理咱们来说下Map的默认值
// 默认值 null
@Value("#{${chilx.person.courses1:{}}}")
private Map<String, String> courses1;
// 默认值 null
@Value("#{${chilx.person.courses1:null}}")
private Map<String, String> courses2;
// 默认值 {k1:v1}
@Value("#{${chilx.person.courses1:{k1:'v1'}}}")
private Map<String, String> courses3;
可以看到,默认值的设置都大同小异
字典类型和集合类型一样,也是有其他的配置方式的,只是也是不支持@Value的注入方式,休息下我们继续哈
春去秋来,一晃眼十… 咳咳扯远了,继续继续
5、ConfigurationProperties
前面咱们不是讲过集合类型和字典类型还有其他的的注入方式呀,现在咱们趁热打铁学习一下
咱们现在使用的方式是批量绑定配置文件中的属性
- pom.xml中添加相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
-
新创建一个类User
添加对应的类注解,prefix属性对应的是配置文件中的配置的层级,一直到倒数第二级
@ConfigurationProperties(prefix = "chilx.girlfriend")
- 编写配置文件
chilx:
girlfriend:
name: 林妹妹
age: 18
hobbies: 唱歌, 跳舞
friend: 迎春, 惜春
pet1: 大象, 狮子
pet2:
- 老虎
- 豹子
pet3:
小猫
小狗
courses:
k1: 100
k2: 100
- 编写User类
注意:类中的属性要和配置文件中的最后一级的配置名称要一致,强一致,切记切记。如果对应的配置不存在,则属性为null
User类的具体如下
@Component
@Getter
@Setter
@ToString
@ConfigurationProperties(prefix = "chilx.girlfriend")
public class User {
private String name;
private Integer age;
/**
* 默认值为空串
*/
private String gender;
/**
* 不存在为null
*/
private String nikeName;
/**
* 默认值为 男
*/
private String password;
private String[] hobbies;
private List<String> friend;
private List<String> pet1;
private List<String> pet2;
private List<String> pet3;
private Map<String, Integer> courses;
做完上面几步就对属性绑定完成了,是不是简单
林妹妹:是挺简单,感觉比@Value方便多了,可以一次批量绑定,就是没有@Value灵活
博主:鱼和熊掌不可兼得耶
ConfigurationProperties不仅可以绑定属性连对象都可以绑定,我给你演示下
- 在配置文件中添加以下配置
chilx:
girlfriend:
.....
boyfriend: {name: chilx, age: 18 }
- 在User类中添加对应属性
private Boyfriend boyfriend;
以上两步就解决了,是不是很简单,是不是很简单
@Value和ConfigurationProperties的却别
- @Value属性填充是在bean实例化后调用populateBean(),由AutowiredAnnotationBeanPostProcessor注入填充
- @ConfigurationProperties的属性填充,是在initializeBean时, 由ConfigurationPropertiesBindingPostProcessor注入填充
结论:如果一个字段同时被两种方式进行填充,最终填充是由@ConfigurationProperties决定
6、附加
开始我们不是说了集合类型其他方式的配置@Value不能绑定数据,这里我们演示下
配置文件添加中修改下配置
chilx:
person:
friend:
- 迎春
- 惜春
执行代码发下报错
我们先看下报错
这个错的意思不能解析咱们配置的参数,这下知道了不
7、结束语
博主:讲到现在你差不多对spring的数据绑定有了初步的认识了吧?
林妹妹:嗯嗯,谢谢哥哥
博主:傻瓜,今天我讲的的这些知识数据绑定的皮毛,还有很多高级的应用,有时间我在给你讲下
一会我把测试代码提交的github和马云你要是记不住,到时候可以参考下。
话音刚落,博主开始的打开浏览器想看FPX和RNG的比赛,悲痛的发现已经比赛完了FPX:RNG 3:0 这个结果有点出乎意料呀。
快速的看了下回放,发下这几句都是正反手教学呀,RNG需要反思了呀,还有刘青松的瑞尔是真的强,瑞尔king呀!!!
画外音:博主你哪有什么女朋友!!!!