SpringBoot数据绑定

引言

SpringBoot中属性自动绑定是依赖 @ConfigurationProperties注解,这个注解的实现是基于BeanPostprocessor

也就是ConfigurationPropertiesBindingPostProcessor

我遇到的场景是在自动绑定枚举类型的字段的时候,配置的value是小写,也能正常绑定,所以探索下是如何实现的。

流程解析

以下是主要的流程(基于SpringBoot 2.3.0):

首先是后置处理器来处理

org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization

接下来就是一系列的方法调用,去解析我们需要的属性值

org.springframework.boot.context.properties.ConfigurationPropertiesBinder#bind
org.springframework.boot.context.properties.bind.JavaBeanBinder#bind(org.springframework.boot.context.properties.bind.JavaBeanBinder.BeanSupplier<T>, org.springframework.boot.context.properties.bind.DataObjectPropertyBinder, org.springframework.boot.context.properties.bind.JavaBeanBinder.BeanProperty)
org.springframework.boot.context.properties.bind.Binder#bindDataObject
org.springframework.boot.context.properties.bind.Binder#bindObject
org.springframework.boot.context.properties.bind.Binder#bindProperty

当解析出来之后此时还是个String类型的对象,我们还需要把他转成我们指定的类型

org.springframework.boot.context.properties.bind.BindConverter#convert(java.lang.Object, org.springframework.core.ResolvableType, java.lang.annotation.Annotation...)
org.springframework.boot.context.properties.bind.BindConverter.CompositeConversionService#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor)
org.springframework.core.convert.support.GenericConversionService#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor)
org.springframework.core.convert.support.ConversionUtils#invokeConverter
org.springframework.boot.convert.LenientObjectToEnumConverterFactory.LenientToEnumConverter#convert
## 这个方法可以看下,做了兼容    
org.springframework.boot.convert.LenientObjectToEnumConverterFactory.LenientToEnumConverter#findEnum

上面解析好之后,通过类型转换器(ConversionService)转换成我们期望的类型,然后通过反射把属性设置完成整个步骤

org.springframework.boot.context.properties.bind.Binder#bindDataObject
org.springframework.boot.context.properties.bind.JavaBeanBinder#bind(org.springframework.boot.context.properties.bind.JavaBeanBinder.BeanSupplier<T>, org.springframework.boot.context.properties.bind.DataObjectPropertyBinder, org.springframework.boot.context.properties.bind.JavaBeanBinder.BeanProperty)

总结

在绑定枚举类型的数据的时候,SpringBoot做了兼容,如果无法转换成枚举的时候,会根据枚举类型获取所有的枚举,并把枚举的name全部转成小写再匹配一次,从而实现如果配置的属性的值是小写但是枚举类型的name属性(枚举类型有个默认的name属性)是大写也能正常绑定。其实现核心就是Spring的BeanPostProcessor.

需要注意这个和Spring的@Value注解的处理没有什么关系,但是它们俩的属性数据源是相同的。Spring的@Value是在实例化Bean的时候的populateBean()方法中注入的。@Value属性的key必须完全一致才能注入;而SpringBoot的属性自动绑定是支持松散绑定的,也就是说你的key可以是大小写、驼峰、中划线等,都能够去匹配,而且推荐的是中划线的模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值