源码分析 | BeanWrapper获取Bean属性实现

Posted 极客小智

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码分析 | BeanWrapper获取Bean属性实现相关的知识,希望对你有一定的参考价值。

导读: BeanWrapper接口 ,作为spring内部的一个核心接口,正如其名,它是bean的包裹类,即在内部中将会保存该bean的实例,提供其它一些扩展功能。


BeanWrapper接口还继承了PropertyAccessor, propertyEditorRegistry, TypeConverter、ConfigurablePropertyAccessor接口,所以它还提供了访问bean的属性值、属性编辑器注册、类型转换等功能。


下面我们一起回顾一下bean的实例化过程,看一下spring是怎么使用BeanWrapper。


Bean的实例化过程

  • ResourceLoader加载配置信息

  • BeanDefinitionReader读取并解析bean属性,并将bean的属性转换为BeanDefinition对应的属性,并注册到BeanDefinitionRegistry注册表中。

  • 容器扫描BeanDefinitionRegistry注册表,通过反射机制获取BeanFactoryPostProcessor类型的工厂后处理器,并用这个工厂后处理器对BeanDefinition进行加工。

  • 根据处理过的BeanDefinition,实例化bean。然后BeanWrapper结合BeanDefinitionRegistry和PropertyEditorRegistry对Bean的属性赋值。


简单可以归纳为Bean的创建都是BeanDefinition ==> BeanWrapper ==>Bean 这三个步骤,BeanWrapper 之所以具备编辑、类型转换 等这些功能,是由于继承了ConfigurablePropertyAccessor、PropertyAccessor, PropertyEditorRegistry, TypeConverter 这些接口.

源码分析 | BeanWrapper获取Bean属性实现


源码分析 | BeanWrapper获取Bean属性实现


看完这个例子,大致对里面的方法有一些了解,接下来我们继续看源码的相关逻辑.

源码解读

BeanWrapper

BeanWrapper 是底层JavaBeans 的中央接口.一般不会被直接调用,而是隐含的被BeanFactory 或者DataBinder使用.


具有(单独或批量)获取和设置属性值,获取属性描述符以及查询属性的可读性/可写性的能力.

该接口支持嵌套属性,可将子属性上的属性设置为无限深度.


BeanWrapper的“ extractOldValueForEditor”默认值为false,以避免由getter方法调用引起的副作用。将此选项设置为true,即自定义编辑器公开当前属性值。


BeanWrapper继承了ConfigurablePropertyAccessor、PropertyAccessor, PropertyEditorRegistry, TypeConverter 这些接口. BeanWrapper主要有如下方法:

源码分析 | BeanWrapper获取Bean属性实现

BeanWrapper 的默认实现类BeanWrapperImpl 这里 主要看一下getPropertyDescriptor(String propertyName) 的逻辑:

源码分析 | BeanWrapper获取Bean属性实现


源码分析 | BeanWrapper获取Bean属性实现

源码分析 | BeanWrapper获取Bean属性实现

TypeConverter

TypeConverter 定义类型转换方法的接口:通常(但不一定)与PropertyEditorRegistry接口结合实现。由于TypeConverter实现通常基于不是线程安全的PropertyEditor,TypeConverters本身也不被认为是线程安全的。

对应的实现在 TypeConverterSupport类里面(DataBinder也有对应的实现,这里主要涉及上图相关的), 但是具体的实现都是在 TypeConverterDelegate 类里面

PropertyEditorRegistry

封装用于注册JavaBeans 的方法

PropertyAccessor

访问定义的属性的的通用接口,例如:一个对象的bean 属性或者 一个字段

总结

BeanWrapper 相当于是Spring中的一个包装类,对Bean 进行包装,具有(单独或批量)获取和设置属性值,获取属性描述符以及查询属性的可读性/可写性的能力。

- END 

往期推荐