原文章:https://blog.csdn.net/qq_41907991/article/details/105214244
作者对此进行整理并发布
BeanWrapper是已经将bean创建好了以后,需要用一个包装层来表示这个bean以便于更好的bean之间的通讯,而Beandefinition 是创建前需要用到的信息
BeanWrapper——根接口
PropertyDescriptor:属性描述符,能够描述javaBean中的属性,通过属性描述符我们能知道这个属性的类型,获取到操纵属性的方法(getter/setter)
public interface BeanWrapper extends ConfigurablePropertyAccessor {
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
int getAutoGrowCollectionLimit();
Object getWrappedInstance();// 获取包装的Bean
Class<?> getWrappedClass();// 获取包装的Bean的class
PropertyDescriptor[] getPropertyDescriptors();// 获取所有属性的属性描述符
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;// 获取指定属性的属性描述符
}
BeanWrapperImpl——实现类
public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper {
// 缓存内省的结果,BeanWrapperImpl就是通过这个对象来完成对包装的Bean的属性的控制
@Nullable
private CachedIntrospectionResults cachedIntrospectionResults;
......
public void setBeanInstance(Object object) {
this.wrappedObject = object;
this.rootObject = object;
// 实际进行类型转换的对象:typeConverterDelegate
this.typeConverterDelegate = new TypeConverterDelegate(this, this.wrappedObject);
setIntrospectionClass(object.getClass());
}
......
// 最终调用的就是CachedIntrospectionResults的forClass方法进行内省并缓存,底层调用的就是java的内省机制
private CachedIntrospectionResults getCachedIntrospectionResults() {
if (this.cachedIntrospectionResults == null) {
this.cachedIntrospectionResults = CachedIntrospectionResults.forClass(getWrappedClass());
}
return this.cachedIntrospectionResults;
}
.......
// 最终进行类型转换的方法
private Object convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue,
@Nullable Object newValue, @Nullable Class<?> requiredType, @Nullable TypeDescriptor td)
throws TypeMismatchException {
Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate");
try {
// 可以看到,最后就是调用typeConverterDelegate来进行类型转换
return this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, requiredType, td);
}
......
}
}
定义和保存的包装的bean以及实现属性访问的具体实现
主要定义流程
内置了一个TypeConverterDelegate
实现类型转化的具体实现
这个类最大的作用在于管理PropertyEditor,添加了很多的默认的PropertyEditor。在PropertyEditorRegistry的基础上做了进一步的扩展,提供的还是属性编辑器注册的功能。
可以看得出内置了很多Map,都是用Class作为key去拿出
class TypeConverterDelegate {
private final PropertyEditorRegistrySupport propertyEditorRegistry;
@Nullable
private final Object targetObject;
public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue,
@Nullable Class<T> requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException {
// 查看是否为当前这个类型配置了定制的PropertyEditor
PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
ConversionFailedException conversionAttemptEx = null;
// 获取当前容器中的类型转换业务类
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
// 在这里可以看出,Spring底层在进行类型转换时有两套机制
// 1.首选的是采用PropertyEditor
// 2.在没有配置PropertyEditor的情况下,会采用conversionService
if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
try {
// 通过conversionService进行类型转换
return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
}
catch (ConversionFailedException ex) {
// fallback to default conversion logic below
conversionAttemptEx = ex;
}
}
}
Object convertedValue = newValue;
// 配置了定制的属性编辑器,采用PropertyEditor进行属性转换
if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
if (typeDescriptor != null && requiredType != null && Collection.class.isAssignableFrom(requiredType) &&
convertedValue instanceof String) {
TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor();
if (elementTypeDesc != null) {
Class<?> elementType = elementTypeDesc.getType();
if (Class.class == elementType || Enum.class.isAssignableFrom(elementType)) {
convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
}
}
}
if (editor == null) {
// 没有配置定制的属性编辑器,采用默认的属性编辑器
editor = findDefaultEditor(requiredType);
}
// 采用属性编辑器进行转换,需要注意的是,默认情况下PropertyEditor只会对String类型的值进行类型转换
convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
}
// .....
return (T) convertedValue;
}
}
从上面的代码中我们可以知道,Spring在实现类型转换时,有两套机制,第一套机制依赖于PropertyEditor,第二套机制依赖于ConversionService。
关于属性编辑器PropertyEditor我们之前已经介绍过了,主要进行的是String到Object的转换
,正因为如此,属性编辑器进行类型转换有很大的局限性,所以Spring又推出了一套ConversionService的体系。
Converter
package org.springframework.core.convert.converter;
public interface Converter<S, T> {// 将一个S=>数据转换>T类型
T convert(S source);
}
ConverterFactory
public interface ConversionService {
// 判断是否能进行类型转换
boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);
boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
// 进行类型转换
@Nullable
<T> T convert(@Nullable Object source, Class<T> targetType);
@Nullable
Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
}
GenericConverter
ConversionService+ConverterRegistry=>ConfigurableConversionService
GenericConversionService/DefaultConversionService