序言
经过前面一系列的加载、解析等准备工作,此刻refresh方法的执行已经来到了尾声,接下来我们用几篇文章着重的介绍一下Bean的初始化
代码
着重看refresh()主流程
中的finishBeanFactoryInitialization()
方法。
finishBeanFactoryInitialization
方法首先会判断beanFactory中是否包含ConversionService,并设置属性。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.// 如果包含ConversionService,则赋值给conversionService变量if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}//省略部分源码...}
扩展:ConversionService
我们经常会在页面进行各种各样的输入 abcd,1234等 这些输入是如何变换成指定的类型的呢?。
看看beanFacroty设置的ConversionService是什么?如果我们想要自定义ConversionService改如何实现?
ConversionService
Spring的提供的ConversionService接口,里面包含判断canConvert()
方法判断是否可以进行类型转换,convert
方法进行类型的转换。接口的实现类有很多,我们主要看DefaultConversionService
即可。
/*** 类型转换服务*/
public interface ConversionService {/*** 判断sourceType是否能转换成targetType*/boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);@Nullable<T> T convert(@Nullable Object source, Class<T> targetType);@NullableObject convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);
}
DefaultConversionService
DefaultConversionService
下分别有addDefaultConverters
、addCollectionConverters
、addScalarConverters
三个方法,会在DefaultConversionService初始化时添加各种类型的Converter,以便我们使用时直接拿。我们看一下源码:
public class DefaultConversionService extends GenericConversionService {@Nullableprivate static volatile DefaultConversionService sharedInstance;public DefaultConversionService() {addDefaultConverters(this);}public static void addDefaultConverters(ConverterRegistry converterRegistry) {addScalarConverters(converterRegistry);addCollectionConverters(converterRegistry);converterRegistry.addConverter(new StringToTimeZoneConverter());//添加各种Converter。。。。}public static void addCollectionConverters(ConverterRegistry converterRegistry) {ConversionService conversionService = (ConversionService) converterRegistry;converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));//添加各种Converter。。。。}private static void addScalarConverters(ConverterRegistry converterRegistry) {//省略部分源码converterRegistry.addConverterFactory(new StringToNumberConverterFactory());//添加各种ConverterFacroty。。。。}
}
Converter接口
addDefaultConverters方法。
StrinToimeZoneConverter
类继承了Converter,而Converter接口中的convert方法会将参数S 转换成 T类型
。
class StringToTimeZoneConverter implements Converter<String, TimeZone> {@Overridepublic TimeZone convert(String source) {return StringUtils.parseTimeZoneString(source);}
}@FunctionalInterface
public interface Converter<S, T> {/** S 转换成 T类型* Convert the source object of type {@code S} to target type {@code T}.* @param source the source object to convert, which must be an instance of {@code S} (never {@code null})* @return the converted object, which must be an instance of {@code T} (potentially {@code null})* @throws IllegalArgumentException if the source cannot be converted to the desired target type*/@NullableT convert(S source);
}
ConditionalGenericConverter
addCollectionConverters方法。
ArrayToCollectionConverter
类继承关系
ArrayToCollectionConverter -》ConditionalGenericConverter -》 GenericConverter(ConditionalConverter)
。
其中ConditionalConverter
接口中的match方法可以理解成@Confitional注解,根据传入的 sourceType 和 targetType 来判断是否符合转换。
而GenericConverter
中的convert
方法,会将 source 通过 sourceType的描述 转换成 targetType类型。
final class ArrayToCollectionConverter implements ConditionalGenericConverter {@Overridepublic Set<ConvertiblePair> getConvertibleTypes() {return Collections.singleton(new ConvertiblePair(Object[].class, Collection.class));}@Overridepublic boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), this.conversionService);}public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {// 。。。。。。。省略}
}
public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {}
public interface ConditionalConverter {boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}
public interface GenericConverter {/*** Return the source and target types that this converter can convert between.* <p>Each entry is a convertible source-to-target type pair.* <p>For {@link ConditionalConverter conditional converters} this method may return* {@code null} to indicate all source-to-target pairs should be considered.*/@NullableSet<ConvertiblePair> getConvertibleTypes();/*** Convert the source object to the targetType described by the {@code TypeDescriptor}.* @param source the source object to convert (may be {@code null})* @param sourceType the type descriptor of the field we are converting from* @param targetType the type descriptor of the field we are converting to* @return the converted object*/@NullableObject convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType);/*** suorceType 和 targetType的键值对* Holder for a source-to-target class pair.*/final class ConvertiblePair {private final Class<?> sourceType;private final Class<?> targetType;public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {this.sourceType = sourceType;this.targetType = targetType;}public Class<?> getSourceType() {return this.sourceType;}public Class<?> getTargetType() {return this.targetType;}}
}
TypeDescriptor
包含常见基础的类型类和包装类。
public class TypeDescriptor implements Serializable {private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<>(32);private static final Class<?>[] CACHED_COMMON_TYPES = {boolean.class, Boolean.class, byte.class, Byte.class, char.class, Character.class,double.class, Double.class, float.class, Float.class, int.class, Integer.class,long.class, Long.class, short.class, Short.class, String.class, Object.class};static {for (Class<?> preCachedClass : CACHED_COMMON_TYPES) {commonTypesCache.put(preCachedClass, valueOf(preCachedClass));}}
}
ConverterFactory
StringToNumberConverterFactory
final class StringToNumberConverterFactory implements ConverterFactory<String, Number> {@Overridepublic <T extends Number> Converter<String, T> getConverter(Class<T> targetType) {return new StringToNumber<>(targetType);}private static final class StringToNumber<T extends Number> implements Converter<String, T> {private final Class<T> targetType;public StringToNumber(Class<T> targetType) {this.targetType = targetType;}@Overridepublic T convert(String source) {if (source.isEmpty()) {return null;}return NumberUtils.parseNumber(source, this.targetType);}}
}
ConverterFactory
ConverterFactory转换会支持将 S 转换成 T 类型 (T instance of R)。
public interface ConverterFactory<S, R> {/*** 获取转换器** Get the converter to convert from S to target type T, where T is also an instance of R.* @param <T> the target type* @param targetType the target type to convert to* @return a converter from S to T*/<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}