为了账号安全,请及时绑定邮箱和手机立即绑定

003SpringBoot之@ConfigurationProperties与@Value的区别

标签:
SpringBoot

一、两个注解对比


@ConfigurationProperties@Value
来源springbootspring
功能批量注入配置文件中的属性一个个的单独指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

注意:配置文件不管是yml格式还是properties格式,上面两种注解都可以获取的到。

二、来源

package org.springframework.boot.context.properties.ConfigurationProperties {}package org.springframework.beans.factory.annotation.Value {}

三、功能

1、@ConfigurationProperties

指定一个前缀,将配置文件里前缀后面的所有属性都一一映射到JavaBean对应的属性中。

比如:

配置:

person:  lastName: 张三  age: 25  isBoss: false  birth: 2017/12/12  maps: {key1: value1,key2: value2}  lists:    - 雷军    - 乔布斯    - 马云  dog:    name: milly    age: 2

JavaBean:

@ConfigurationProperties(prefix = "person")@Componentpublic class Person {    // 这种驼峰写法在yml里可以用lastName或者last-name,都可以
    private String lastName;    private Integer age;    private boolean isBoss;    private Date birth;    private Map<String, Object> maps;    private List<Object> lists;    private Dog dog;
    ...省略getter/setter/toString...
}

PS:需要将Person指定为SpringBean,@ConfigurationProperties才会生效。

测试类:

@RunWith(SpringRunner.class)@SpringBootTestpublic class Springboot02ConfigApplicationTests {    @Autowired
    private Person person;    @Test
    public void contextLoads() {
        System.out.println(person);
    }
}

测试结果:

Person{lastName='张三', age=25, isBoss=false, birth=Tue Dec 12 00:00:00 CST 2017, maps={key1=value1, key2=value2}, lists=[雷军, 乔布斯, 马云], dog=Dog{name='milly', age=2}}

PS:结果发现我们配置文件里的属性值都赋值到了JavaBean中,符合预期。

2、@Value

类似于Spring配置文件的value属性:

<bean class="Person">
    <property name="lastName" value="zhangsan"></property></bean>

要想完成JavaBean和配置文件的映射,需要在JavaBean中的每个属性上都写上@Value,进行一一匹配。

配置:

同@ConfigurationProperties的配置

JavaBean:

@Componentpublic class Person {    @Value("person.lastName")    private String lastName;    @Value("person.age")    private Integer age;    @Value("person.isBoss")    private boolean isBoss;    private Date birth;    private Map<String, Object> maps;    private List<Object> lists;    private Dog dog;
    ...省略getter/setter/toString...
}

PS:只写了前几个,效果很明显,我们需要写很多@Value注解,在每个属性上都写上,很麻烦。

测试类:

同@ConfigurationProperties的配置

四、松散绑定

1、定义

比如JavaBean里写的是lastName(驼峰写法),配置文件里可以写成lastName,也可以写成last-name。

2、证明

2.1、@ConfigurationProperties

配置:

person:  last-name: 张三

JavaBean:

@ConfigurationProperties(prefix = "person")@Componentpublic class Person {    // 这种驼峰写法在yml里可以用lastName或者last-name,都可以
    private String lastName;
}

运行测试类, 依然可以正常赋值。

2.2、@Value

配置:

person:  last-name: 张三

JavaBean:

@Componentpublic class Person {    @Value("${person.lastName}")    private String lastName;
}

运行测试类,启动会报错

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'person.lastName' in value "${person.lastName}"

五、SpEL

1、@ConfigurationProperties

不支持SpEL表达式,比如年龄字段若写成:#{22 * 2},会出错。

2、@Value

支持SpEL表达式,比如:

@Componentpublic class Person {    @Value("#{22*2}")    private Integer age;
}

输出年龄:44

六、JSR303数据校验

1、@ConfigurationProperties

配置:

person:  lastName: 张三  age: 25  isBoss: false  birth: 2017/12/12  maps: {key1: value1,key2: value2}  lists:    - 雷军    - 乔布斯    - 马云  dog:    name: milly    age: 2

JavaBean:

@ConfigurationProperties(prefix = "person")@Component@Validatedpublic class Person {    @Email
    private String lastName;    private Integer age;    private boolean isBoss;    private Date birth;    private Map<String, Object> maps;    private List<Object> lists;    private Dog dog;
    ...省略getter/setter/toString...
}

测试结果:

- Field error in object 'person' on field 'lastName': rejected value [张三]; codes [Email.person.lastName,Email.lastName,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.lastName,lastName]; arguments []; default message [lastName],[Ljavax.validation.constraints.Pattern$Flag;@54336c81,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@1556f2dd]; default message [不是一个合法的电子邮件地址]; origin class path resource [application.yml]:6:14

2、@Value

配置:

同@ConfigurationProperties的配置

JavaBean:

@Component@Validatedpublic class Person {    @Email
    @Value("${person.last-name}")    private String lastName;    private Integer age;    private boolean isBoss;    private Date birth;    private Map<String, Object> maps;    private List<Object> lists;    private Dog dog;
    ...省略getter/setter/toString...
}

测试结果:

不会出现异常

七、复杂类型封装

1、什么是复杂类型?

比如person里有个maps

2、@ConfigurationProperties

配置:

person:  maps: {key1: value1,key2: value2}

JavaBean:

@ConfigurationProperties(prefix = "person")@Componentpublic class Person {    private Map<String, Object> maps;
}

运行结果:会正常给maps赋值。

3、@Value

配置:

person:  maps: {key1: value1,key2: value2}

JavaBean:

@Componentpublic class Person {    @Value("${person.maps}")    private Map<String, Object> maps;
}

运行结果:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'person.mps' in value "${person.mps}"

八、建议

1、如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value。简单粗暴。

2、如果说,我们专门编写了一个JavaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties注解进行映射。



作者:编程界的小学生
链接:https://www.jianshu.com/p/080654c82fed

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消