Spring通用类型转换的实现原理

Spring通用类型转换的实现原理

    • 设计思路
    • 实现逻辑
      • ConversionService:类型转换服务入口
      • ConverterRegister:转换器注册接口
      • GenericConversionService
        • 1. `Map converters`
        • 2. `canConvert()` 与 `convert()`:服务入口
        • 3. `getConverter()`:匹配最合适的转换器
        • 4. `addConverter()` 和 `addConverterFactory()`
        • 5. `getRequiredTypeInfo()`
        • 6. 完整代码

源码见:mini-spring

在这里插入图片描述

设计思路

在前面我们聊了Spring类型转换的三种实现方式,但现在也遇到一个问题,在后续我们将类型转换融入Spring生命周期的时候对于这三种方式如何选择,如何管理。就从这个角度来看的话,是不是还不如只定义一种方式。

对于这个问题Spring也给出了解决方案:

在类型转换系统中保留一个核心注册接口 + 多种适配实现,是 Spring 推荐的设计;但对于业务开发者或自定义扩展场景,通常只需选择一种实现方式(推荐 Converter)并注册到统一的转换服务中即可。真正集成到 Spring 生命周期中,核心是统一注册到 ConversionService 中。

可以用以下任意方式注册:

GenericConversionService conversionService = new GenericConversionService();  
conversionService.addConverter(new StringToIntegerConverter());  
Integer integer = conversionService.convert("10", Integer.class);  
Assert.assertEquals(Integer.valueOf(10),integer);  
  
conversionService.addConverterFactory(new StringToNumberConverterFactory());  
Long aLong = conversionService.convert("10", Long.class);  
Assert.assertEquals(Long.valueOf(10),aLong);

统一管理入口:通过 ConversionService 统一进行类型转换调用 ,简单来说就是通过适配器模式将Converter与ConverterFactory封装为GenericConverter。

实现逻辑

ConversionService:类型转换服务入口

public interface ConversionService {  
  
    /**  
     * 检查是否可以将源类型转换为目标类型  
     *  
     * @param sourceType 源类型的Class对象  
     * @param targetType 目标类型的Class对象  
     * @return 如果可以进行转换则返回true,否则返回false  
     */    boolean canConvert(Class<?> sourceType, Class<?> targetType);  
  
    /**  
     * 将给定的源对象转换为目标类型  
     *  
     * @param source 要转换的源对象  
     * @param targetType 目标类型的Class对象  
     * @param  目标类型的泛型参数  
     * @return 转换后的目标类型对象  
     */  
    <T> T convert(Object source, Class<T> targetType);  
}
  • 判断是否支持某种类型对的转换

  • 提供统一的类型转换执行入口

ConverterRegister:转换器注册接口

public interface ConverterRegister {  
  
    void addConverter(Converter<?, ?> converter);  
  
    void addConverter(GenericConverter genericConverter);  
  
    void addConverterFactory(ConverterFactory converterFactory);  
}
  • 三种类型转换器的注册入口

  • 最终都会适配为 GenericConverter 存储

GenericConversionService

Spring 支持三种转换器接口(ConverterConverterFactoryGenericConverter),但使用上不应让开发者关心这些差异。

目的:

  • 将三种接口适配为统一的 GenericConverter 类型

  • 统一注册到一个容器(这里是 Map

  • 提供 canConvert()convert() 方法对外暴露转换能力

1. Map converters
  • 核心转换器容器:key 是 “源类型 → 目标类型” 的类型对,value 是对应的转换器。
Map<ConvertiblePair, GenericConverter> converters = new HashMap<>();

2. canConvert()convert():服务入口
@Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType)

判断是否存在某种类型转换器(从 sourceType → targetType

@Override
public <T> T convert(Object source, Class<T> targetType)

实际执行转换,内部通过 getConverter() 获取匹配的 GenericConverter


3. getConverter():匹配最合适的转换器
protected GenericConverter getConverter(Class<?> sourceType, Class<?> targetType)

核心逻辑:

  • 递归获取 source 和 target 的继承结构(getClassHierarchy()

  • 生成 ConvertiblePair 对象

  • converters 中查找是否存在该对的转换器

支持子类转父类、接口匹配等灵活匹配机制


4. addConverter()addConverterFactory()
public void addConverter(Converter<?, ?> converter)
  • 将实现了 Converter 的对象适配为 GenericConverter(通过 ConverterAdapter

  • 注册到 converters 容器中

public void addConverterFactory(ConverterFactory<?, ?> converterFactory)
  • 同理,适配 ConverterFactoryGenericConverter(通过 ConverterFactoryAdapter

5. getRequiredTypeInfo()
private ConvertiblePair getRequiredTypeInfo(Object object)

这个方法利用 反射 + 泛型解析

  • 读取类所实现的接口的泛型参数类型

  • 自动识别该转换器是支持 S → T 哪两个类型

举例:

class StringToIntegerConverter implements Converter<String, Integer>

会被解析为:

ConvertiblePair(String.class, Integer.class)
6. 完整代码

public class GenericConversionService implements ConversionService, ConverterRegister {  
  
    // 用于存储通用转换器  
    private Map<ConvertiblePair,GenericConverter> converters = new HashMap();  
  
  
    /**  
     * 检查是否可以将源类型转换为目标类型  
     *  
     * @param sourceType 源类型的Class对象  
     * @param targetType 目标类型的Class对象  
     * @return 如果可以进行转换则返回true,否则返回false  
     */    @Override  
    public boolean canConvert(Class<?> sourceType, Class<?> targetType) {  
        GenericConverter converter = getConverter(sourceType, targetType);  
        return converter != null;  
    }  
  
    /**  
     * 将给定的源对象转换为目标类型  
     *  
     * @param source     要转换的源对象  
     * @param targetType 目标类型的Class对象  
     * @return 转换后的目标类型对象  
     */  
    @Override  
    public <T> T convert(Object source, Class<T> targetType) {  
        Class<?> sourceType = source.getClass();  
        GenericConverter converter = getConverter(sourceType, targetType);  
        return (T) converter.convert(source, sourceType, targetType);  
    }  
  
    /**  
     * 获取通用适配器  
     * @param sourceType  
     * @param targetType     * @return     */    protected GenericConverter getConverter(Class<?> sourceType, Class<?> targetType){  
        List<Class<?>> sourceHierarchy = getClassHierarchy(sourceType);  
        List<Class<?>> targetHierarchy = getClassHierarchy(targetType);  
  
        for (Class<?> sourceCandidate : sourceHierarchy) {  
            for (Class<?> targetCandidate : targetHierarchy) {  
                ConvertiblePair convertiblePair = new ConvertiblePair(sourceCandidate, targetCandidate);  
                GenericConverter genericConverter = converters.get(convertiblePair);  
                if (genericConverter != null){  
                    return genericConverter;  
                }  
            }  
              
        }  
        return null;  
    }  
  
    // 获取目标类的完整继承层级结构,以便于通过ConvertiblePair判断转换器是否已注册  
    protected List<Class<?>> getClassHierarchy(Class<?> clazz){  
        List<Class<?>>  hierarchy = new ArrayList<>();  
        while ((clazz != null)){  
            hierarchy.add(clazz);  
            clazz = clazz.getSuperclass();  
        }  
        return hierarchy;  
    }  
  
  
    @Override  
    public void addConverter(Converter<?, ?> converter) {  
        // 这里传入的是一个Converter转换器对象,我们需要将其转化为GenericConverter对象  
        ConvertiblePair requiredTypeInfo = getRequiredTypeInfo(converter);  
        ConverterAdapter converterAdapter = new ConverterAdapter(converter, requiredTypeInfo);  
        for (ConvertiblePair convertibleType : converterAdapter.getConvertibleTypes()) {  
            converters.put(convertibleType,converterAdapter);  
        }  
  
    }  
  
    @Override  
    public void addConverterFactory(ConverterFactory converterFactory) {  
        ConvertiblePair requiredTypeInfo = getRequiredTypeInfo(converterFactory);  
        ConverterFactoryAdapter converterFactoryAdapter = new ConverterFactoryAdapter(converterFactory, requiredTypeInfo);  
        for (ConvertiblePair convertibleType : converterFactoryAdapter.getConvertibleTypes()) {  
            converters.put(convertibleType,converterFactoryAdapter);  
        }  
    }  
  
  
    /**  
     * 获取到目标类所实现的泛型接口的元素  
     * @param object  
     * @return     */    private ConvertiblePair getRequiredTypeInfo(Object object){  
        Type[] types = object.getClass().getGenericInterfaces();  
        ParameterizedType parameterized = (ParameterizedType) types[0];  
        Type[] actualTypeArguments = parameterized.getActualTypeArguments();  
        Class sourceType = (Class) actualTypeArguments[0];  
        Class targetType = (Class) actualTypeArguments[1];  
        return new ConvertiblePair(sourceType, targetType);  
    }  
  
  
    // 通过适配器模式对Converter以及ConverterFactory进行适配  
    private final class ConverterAdapter implements GenericConverter{  
  
        private final Converter converter;  
  
        private final ConvertiblePair convertiblePair;  
  
        private ConverterAdapter(Converter converter, ConvertiblePair convertiblePair) {  
            this.converter = converter;  
            this.convertiblePair = convertiblePair;  
        }  
  
        @Override  
        public Object convert(Object source, Class sourceType, Class targetType) {  
            return converter.convert(source);  
        }  
  
        @Override  
        public Set<ConvertiblePair> getConvertibleTypes() {  
            return Collections.singleton(convertiblePair);  
        }  
    }  
  
    private final class ConverterFactoryAdapter implements GenericConverter{  
        private final ConverterFactory converterFactory;  
  
        private final ConvertiblePair convertiblePair;  
  
        private ConverterFactoryAdapter(ConverterFactory converterFactory, ConvertiblePair convertiblePair) {  
            this.converterFactory = converterFactory;  
            this.convertiblePair = convertiblePair;  
        }  
  
        @Override  
        public Object convert(Object source, Class sourceType, Class targetType) {  
            return converterFactory.getConverter(targetType).convert(source);  
        }  
  
        @Override  
        public Set<ConvertiblePair> getConvertibleTypes() {  
            return Collections.singleton(convertiblePair);  
        }  
    }  
}

你可能感兴趣的:(Spring源码分析,spring,java,ajax)