Spring 系列目录(http://www.javashuo.com/article/p-hskusway-em.html)html
BeanWrapper 位于 org.springframework.beans 包中,默认实现为 BeanWrapperImpl,提供分析和处理标准 JavaBean 用于 get 和 set 属性,取得属性描述,查询属性的读/写能力。java
beans 包还提供了一个 PropertyValues 用于保存多个属性值,默认的实现 MutablePropertyValues。另外还有两个有用的工具类,BeanUtils 和 PropertyAccessorUtils。spring
PropertyEditorRegistry
PropertyEditor 注册、查找。TypeConverter
类型转换,其主要的工做由 TypeConverterDelegate 这个类完成的。PropertyAccessor
属性读写。ConfigurablePropertyAccessor
配置一些属性,如设置 ConversionService、是否暴露旧值、嵌套注入时属性为 null 是否自动建立。BeanWrapper
对 bean 进行封装。AbstractNestablePropertyAccessor
实现了对嵌套属性注入的处理,其它实现见名知义就不介绍了。BeanWrapper 的层次结构仍是比较清晰的,继承于 ConfigurablePropertyAccessor 和 PropertyAccessor 接口。数组
有一点不太明白,为何 BeanWrapper 要继承于 PropertyEditorRegistry。从字面意义上来讲,PropertyEditorRegistry 提供了 PropertyEditor,而 TypeConverter 进行类型转换,和 BeanWrapper 不是继承关系,使用组合感受更好。app
PropertyEditor 将 String 转换为其它类型,PropertyEditorRegistry 统一管理全部的 PropertyEditor 注册和查找。编辑器
public interface PropertyEditorRegistry { // 1. 根据类型注册 PropertyEditor void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor); // 2. 根据类型(requiredType)和属性(propertyPath)注册 PropertyEditor // 查找时优先根据 propertyPath 查找对应的 PropertyEditor,propertyPath 能够为嵌套属性 void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor); // 3. 根据类型和属性查找 PropertyEditor PropertyEditor findCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath); }
PropertyEditorRegistry 的实现类 PropertyEditorRegistrySupport 分析见这两篇文章:ide
TypeConverter 负责类型转换,其主要的工做由 TypeConverterDelegate 这个类完成的。工具
public interface TypeConverter { // 1. value 转换成 requiredType <T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException; // 2. methodParam 同下 <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException; // 3. field 是 value 转换成 requiredType 后须要赋值的 field 字段 // 能够从该 field 字段拿到其泛型信息,从而进一步判断是否能够转换,毕竟 requiredType 只有 Class 信息 <T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) throws TypeMismatchException; }
TypeConverter 的实现类 TypeConverterSupport 的全部功能,实际是都是委托给 TypeConverterDelegate 完成的。源码分析
PropertyAccessor 提供了对 JavaBean 的基本操做。ui
public interface PropertyAccessor { boolean isReadableProperty(String propertyName); boolean isWritableProperty(String propertyName); Class<?> getPropertyType(String propertyName) throws BeansException; TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException; Object getPropertyValue(String propertyName) throws BeansException; void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException; void setPropertyValue(PropertyValue pv) throws BeansException; void setPropertyValues(Map<?, ?> map) throws BeansException; void setPropertyValues(PropertyValues pvs) throws BeansException; void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown) throws BeansException; void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException; }
PropertyAccessor 的实现类是 AbstractPropertyAccessor,这个类中 setPropertyValue 进行了处理,最终都是调用 setPropertyValue(String propertyName, Object value) 完成属性注入。
public interface ConfigurablePropertyAccessor extends PropertyAccessor, PropertyEditorRegistry, TypeConverter { void setConversionService(@Nullable ConversionService conversionService); ConversionService getConversionService(); // PropertyEditor 使用时是否暴露修改先后值 void setExtractOldValueForEditor(boolean extractOldValueForEditor); boolean isExtractOldValueForEditor(); // 嵌套注入时当属性为 null 时是否自动生成对象 void setAutoGrowNestedPaths(boolean autoGrowNestedPaths); boolean isAutoGrowNestedPaths(); }
ConfigurablePropertyAccessor 的实现也类是 AbstractPropertyAccessor,这个类中默认 extractOldValueForEditor 和 autoGrowNestedPaths 都是 false,即不暴露旧值,也不支持嵌套注入时属性为 null 就自动建立对象。
public interface BeanWrapper extends ConfigurablePropertyAccessor { // @since 4.1 设置集合或数组自动生成对象的最大嵌套深度 void setAutoGrowCollectionLimit(int autoGrowCollectionLimit); int getAutoGrowCollectionLimit(); Object getWrappedInstance(); Class<?> getWrappedClass(); PropertyDescriptor[] getPropertyDescriptors(); PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException; }
BeanWrapper 的实现类是 BeanWrapperImpl,主要完成了 JavaBean 的内省,包括 PropertyDescriptor 的获取,属性的赋值等。
(1) JavaBean 的内省
private CachedIntrospectionResults cachedIntrospectionResults; // 获取 private CachedIntrospectionResults getCachedIntrospectionResults() { if (this.cachedIntrospectionResults == null) { this.cachedIntrospectionResults = CachedIntrospectionResults.forClass(getWrappedClass()); } return this.cachedIntrospectionResults; }
JavaBean 的内省都是由 CachedIntrospectionResults 完成,经过 cachedIntrospectionResults 就能够获取对应属性的 PropertyDescriptor。例以下面两个方法:
@Override public PropertyDescriptor[] getPropertyDescriptors() { return getCachedIntrospectionResults().getPropertyDescriptors(); } @Override public PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException { BeanWrapperImpl nestedBw = (BeanWrapperImpl) getPropertyAccessorForPropertyPath(propertyName); // 获取属性名称 String finalPath = getFinalPath(nestedBw, propertyName); PropertyDescriptor pd = nestedBw.getCachedIntrospectionResults().getPropertyDescriptor(finalPath); return pd; }
(2) BeanPropertyHandler
@Override protected BeanPropertyHandler getLocalPropertyHandler(String propertyName) { PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName); return (pd != null ? new BeanPropertyHandler(pd) : null); }
BeanPropertyHandler 是 BeanWrapperImpl 的内部类,是对 PropertyDescriptor 的封装,完成对属性的各类操做,如赋值。
(3) convertForProperty
convertForProperty 在 AbstractAutowireCapableBeanFactory#applyPropertyValues 属性注入时使用
public Object convertForProperty(@Nullable Object value, String propertyName) throws TypeMismatchException { CachedIntrospectionResults cachedIntrospectionResults = getCachedIntrospectionResults(); PropertyDescriptor pd = cachedIntrospectionResults.getPropertyDescriptor(propertyName); if (pd == null) { throw new InvalidPropertyException(getRootClass(), getNestedPath() + propertyName, "No property '" + propertyName + "' found"); } TypeDescriptor td = cachedIntrospectionResults.getTypeDescriptor(pd); if (td == null) { td = cachedIntrospectionResults.addTypeDescriptor(pd, new TypeDescriptor(property(pd))); } // 父类 AbstractNestablePropertyAccessor 进行类型转换 return convertForProperty(propertyName, null, value, td); } // Property 也是对 PropertyDescriptor 封装,在 Android 等环境中不存在 PropertyDescriptor 类 private Property property(PropertyDescriptor pd) { GenericTypeAwarePropertyDescriptor gpd = (GenericTypeAwarePropertyDescriptor) pd; return new Property(gpd.getBeanClass(), gpd.getReadMethod(), gpd.getWriteMethod(), gpd.getName()); }
天天用心记录一点点。内容也许不重要,但习惯很重要!