Spring源码 --- Spring的类型转换(TypeConverterDelegate与TypeConverterSupport)

要知道spring的类型转换,我们首先需要知道两个接口。这两个接口就是类型转换的处理类,一个是spring自己定义的,一个是jdk定义的:

Spring定义的Converter接口:

@FunctionalInterface
public interface Converter<S, T> {
   @Nullable
   T convert(S source);
}

Jdk定义的PropertyEditor接口:

public interface PropertyEditor {
    void setValue(Object value);
    Object getValue();
    boolean isPaintable();
    void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box);
    String getJavaInitializationString();
    String getAsText();
    void setAsText(String text) throws java.lang.IllegalArgumentException;
    String[] getTags();
    java.awt.Component getCustomEditor();
    boolean supportsCustomEditor();
    void addPropertyChangeListener(PropertyChangeListener listener);
    void removePropertyChangeListener(PropertyChangeListener listener);
}

这个PropertyEditor用于类型转换的是setAsText、getAsText、getValue、setValue这些方法。

可以看到Converter这里用了泛型、而PropertyEditor并没有。所以,如果调用getValue方法,获取的是Object对象。获取后还需要再转换为我们的目的对象。

这两个Converter、PropertyEditor接口只是接口,下面我们来看下其的实现类。

 

     一、Converter接口

           Converter接口只有一个convert方法,但我们知道,在进行类型转换前,我们一般会先判断其能不能转换为目的类型。所以其实Converter还会搭配ConditionalConverter接口,判断能不能转换:

public interface ConditionalConverter {
   boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}

这两个在组合为一个ConditionalGenericConverter接口:

public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
}

这里GenericConverter接口,我们先将其看做为Converter接口(但其并有继承Converter接口,只是一个独立接口,在Spring的使用中,实现Converter接口的类最后还是会表叙为GenericConverter接口,这个到后面的代码就明白了),

public interface GenericConverter {
   @Nullable
   Set<ConvertiblePair> getConvertibleTypes();

   @Nullable
   Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType);

   final class ConvertiblePair {
      private final Class<?> sourceType;
      private final Class<?> targetType;

         public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
         Assert.notNull(sourceType, "Source type must not be null");
         Assert.notNull(targetType, "Target type must not be null");
         this.sourceType = sourceType;
         this.targetType = targetType;
      }

      public Class<?> getSourceType() {
         return this.sourceType;
      }

      public Class<?> getTargetType() {
         return this.targetType;
      }
................
}

ConvertiblePair 就是哟本来存源类型,目标类型。

我们先简单看一个Converter接口的实现类:NumberToCharacterConverter ,将Number类型转换为Character类型

final class NumberToCharacterConverter implements Converter<Number, Character> {

   @Override
   public Character convert(Number source) {
      return (char) source.shortValue();
   }

}

通过这个我们可以知道Converter在Spring的实现过程。

接下来我们看下其的使用过程,我们看下这个转换器在哪里使用。其是在DefaultConversionService类中被注册:

private static void addScalarConverters(ConverterRegistry converterRegistry) {
   converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());
     ..............
   converterRegistry.addConverter(new NumberToCharacterConverter());
   converterRegistry.addConverterFactory(new CharacterToNumberFactory());
   converterRegistry.addConverter(new StringToBooleanConverter());
    ................
}
public static void addDefaultConverters(ConverterRegistry converterRegistry) {
   addScalarConverters(converterRegistry);
   addCollectionConverters(converterRegistry);
   converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
   ..........
}

这里我们先了解DefaultConversionService、ConverterRegistry。

     

ConverterRegister,这个看名字就知道其是用来注册Converter的:

   

这里有四种类型注册。在这里我们看到可以注册Converter以及GenericConverter,还有ConverterFactory,就是生成Converter 的工厂。

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);
}

ConversionService 这个接口就是用来判断能不能进行转换,以及进行转换的。

public interface ConfigurableConversionService extends ConversionService, ConverterRegistry {
}

其实现类GenericConversionService

  GenericConversionService类有两个成员变量:

private final Converters converters = new Converters();

private final Map<ConverterCacheKey, GenericConverter> converterCache = new ConcurrentReferenceHashMap<>(64);
@Override
public void addConverter(Converter<?, ?> converter) {
   ResolvableType[] typeInfo = getRequiredTypeInfo(converter.getClass(), Converter.class);
   if (typeInfo == null && converter instanceof DecoratingProxy) {
      typeInfo = getRequiredTypeInfo(((DecoratingProxy) converter).getDecoratedClass(), Converter.class);
   }
    ..........
   addConverter(new ConverterAdapter(converter, typeInfo[0], typeInfo[1]));
}
@Nullable
private ResolvableType[] getRequiredTypeInfo(Class<?> converterClass, Class<?> genericIfc) {
   ResolvableType resolvableType = ResolvableType.forClass(converterClass).as(genericIfc);
   ResolvableType[] generics = resolvableType.getGenerics();
   if (generics.length < 2) {
      return null;
   }
   Class<?> sourceType = generics[0].resolve();
   Class<?> targetType = generics[1].resolve();
   if (sourceType == null || targetType == null) {
      return null;
   }
   return generics;
}

可以看到这个getRequiredTypeInfo就用来获取Converter<?, ?>中的两个表示泛型的类型,例如前面的NumberToCharacterConverter implements Converter<Number, Character>,然后就会获取Number, Character,再与Converter以前转换为ConverterAdapter:

private final class ConverterAdapter implements ConditionalGenericConverter {
   private final Converter<Object, Object> converter;
   private final ConvertiblePair typeInfo;
   private final ResolvableType targetType;
   public ConverterAdapter(Converter<?, ?> converter, ResolvableType sourceType, ResolvableType targetType) {
      this.converter = (Converter<Object, Object>) converter;
      this.typeInfo = new ConvertiblePair(sourceType.resolve(Object.class), targetType.resolve(Object.class));
      this.targetType = targetType;
   }
   @Override
   public Set<ConvertiblePair> getConvertibleTypes() {
      return Collections.singleton(this.typeInfo);
   }
   @Override
   public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
      if (this.typeInfo.getTargetType() != targetType.getObjectType()) {
         return false;
      }
      ResolvableType rt = targetType.getResolvableType();
      if (!(rt.getType() instanceof Class) && !rt.isAssignableFrom(this.targetType) &&
            !this.targetType.hasUnresolvableGenerics()) {
         return false;
      }
      return !(this.converter instanceof ConditionalConverter) ||
            ((ConditionalConverter) this.converter).matches(sourceType, targetType);
   }

   @Override
   @Nullable
   public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
      if (source == null) {
         return convertNullSource(sourceType, targetType);
      }
      return this.converter.convert(source);
   }
      ..............
}

ConverterAdapter是实现了ConditionalGenericConverter 接口,所以其需要实现GenericConverter的convert方法、以及ConditionalConverter的是否匹配,即是否能用本Converter去转换。同时会将Converter的源类型以及目标类型存到ConvertiblePair。所以这里就将前面的GenericConverter与Converter 的关系理清了。Converter会被转换到ConverterAdapter,ConverterAdapter实现了GenericConverter。

我们再回到 addConverter(new ConverterAdapter(converter, typeInfo[0], typeInfo[1]));方法:

其调用的是:

@Override
public void addConverter(GenericConverter converter) {
   this.converters.add(converter);
   invalidateCache();
}

所以这里如果是添加GenericConverter类型,就将其直接添加到converters,如果是添加Converter就将其转换为ConverterAdapter(类型转换适配器)。再调用addConverter(GenericConverter converter)方法,ConverterAdapter实现统一的matchs方法。

private final Converters converters = new Converters();
private static class Converters {
   private final Set<GenericConverter> globalConverters = new LinkedHashSet<>()
   private final Map<ConvertiblePair, ConvertersForPair> converters = new LinkedHashMap<>(36);
   public void add(GenericConverter converter) {
      Set<ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();
      if (convertibleTypes == null) {
         Assert.state(converter instanceof ConditionalConverter,
               "Only conditional converters may return null convertible types");
         this.globalConverters.add(converter);
      }
      else {
         for (ConvertiblePair convertiblePair : convertibleTypes) {
            ConvertersForPair convertersForPair = getMatchableConverters(convertiblePair);
            convertersForPair.add(converter);
         }
      }
   }
   private ConvertersForPair getMatchableConverters(ConvertiblePair convertiblePair) {
      ConvertersForPair convertersForPair = this.converters.get(convertiblePair);
      if (convertersForPair == null) {
         convertersForPair = new ConvertersForPair();
         this.converters.put(convertiblePair, convertersForPair);
      }
      return convertersForPair;
   }

可以看到这里的添加会分情况添加到两个地方:globalConverters、converters。要了解这两种的区别,我们看其find方法,即找到对应的GenericConverter:

首先下ConvertersForPair类

private static class ConvertersForPair {

   private final LinkedList<GenericConverter> converters = new LinkedList<>();

   public void add(GenericConverter converter) {
      this.converters.addFirst(converter);
   }

   @Nullable
   public GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
      for (GenericConverter converter : this.converters) {
         if (!(converter instanceof ConditionalGenericConverter) ||
               ((ConditionalGenericConverter) converter).matches(sourceType, targetType)) {
            return converter;
         }
      }
      return null;
   }
}
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
   ...................
   for (Class<?> sourceCandidate : sourceCandidates) {
      for (Class<?> targetCandidate : targetCandidates) {
         ConvertiblePair convertiblePair = new ConvertiblePair(sourceCandidate, targetCandidate);
         GenericConverter converter = getRegisteredConverter(sourceType, targetType, convertiblePair);
         if (converter != null) {
            return converter;
         }
      }
   }
   return null;
}
private GenericConverter getRegisteredConverter(TypeDescriptor sourceType,
      TypeDescriptor targetType, ConvertiblePair convertiblePair) {

   // Check specifically registered converters
   ConvertersForPair convertersForPair = this.converters.get(convertiblePair);
   if (convertersForPair != null) {
      GenericConverter converter = convertersForPair.getConverter(sourceType, targetType);
      if (converter != null) {
         return converter;
      }
   }
   // Check ConditionalConverters for a dynamic match
   for (GenericConverter globalConverter : this.globalConverters) {
      if (((ConditionalConverter) globalConverter).matches(sourceType, targetType)) {
         return globalConverter;
      }
   }
   return null;
}

这里是先获取添加到converters中的,如果没有再获取globalConverters中的:

   通过前面ConvertersForPair 的getConverter方法,可以知道其在matches是转换为ConditionalGenericConverter,而globalConverters是强转为ConditionalConverter。其中ConditionalGenericConverter继承了ConditionalConverter接口。

所以关于Converer接口,整个使用过程是如果实现Converter接口的类都转换为ConverterAdapter适配器,然后通过这个适配器实现的matches的方法去匹配,及调用converter的convert方法。而如果是添加的GenericConverter类型,通过find方法可以知道,要么同时一起继承ConditionalConverter接口(matches方法),要么直接实现ConditionalGenericConverter,因为

    ConditionalGenericConverter继承了ConditionalConverter与GenericConverter接口。

这里Converter、GenericConverter、ConditionalConverter是怎样在GenericConversionService中使用的已经理清楚了。我们再来看其在Spring中使用过程。

  我们再回到继承GenericConversionService类的DefaultConversionService:

public DefaultConversionService() {
   addDefaultConverters(this);
}

其在初始化的时候就调用addDefaultConverters将默认的Converter添加到该类中,如果需要自己再添加,就可以调用前面介绍的addConverter方法,

哪里使用到这个DefaultConversionService类呢?这里就要知道TypeConverterSupport类,Spring中类型转换就是通过这个类去统筹调度的。先在这里不展开,因为这个类还会用到类型转换的另一个接口PropertyEditer接口。

 

    二、PropertyEditor接口

            这个接口 在Jdk中有个初步实现类:PropertyEditorSupport:

          

public class PropertyEditorSupport implements PropertyEditor {private Object value;
private Object source;
private java.util.Vector<PropertyChangeListener> listeners;
    ..................
public void setValue(Object value) {
    this.value = value;
    firePropertyChange();
}
public Object getValue() {
    return value;
}
public String getAsText() {
    return (this.value != null)
            ? this.value.toString()
            : null;
}
public void setAsText(String text) throws java.lang.IllegalArgumentException {
    if (value instanceof String) {
        setValue(text);
        return;
    }
    throw new java.lang.IllegalArgumentException(text);
}
.............
}

可以看到这里在setValue的时候会去通知Listener。我们看一个Spring关于PropertyEditerSupport的实现类:

public class ByteArrayPropertyEditor extends PropertyEditorSupport {
   @Override
   public void setAsText(@Nullable String text) {
      setValue(text != null ? text.getBytes() : null);
   }
   @Override
   public String getAsText() {
      byte[] value = (byte[]) getValue();
      return (value != null ? new String(value) : "");
   }
}

这里就是将text设置为byte[],所以这个类的成员变量为byte[]。当调用getValue的时候返回的是byte[],调用getAsText的时候是获取转换为byte的String。看下Spring中的测试用例:

@Test
public void sunnyDaySetAsText() throws Exception {
   final String text = "Hideous towns make me throw... up";
   byteEditor.setAsText(text);

   Object value = byteEditor.getValue();
   assertNotNull(value);
   assertTrue(value instanceof byte[]);
   byte[] bytes = (byte[]) value;
   for (int i = 0; i < text.length(); ++i) {
      assertEquals("cyte[] differs at index '" + i + "'", text.charAt(i), bytes[i]);
   }
   assertEquals(text, byteEditor.getAsText());
}

这里在getValue的时候要强转换为byte[]。

 

    三、现在我们来看TypeConverterSupport

                                                           

public interface TypeConverter {
   @Nullable
   <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType) throws TypeMismatchException;
   @Nullable
   <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
         @Nullable MethodParameter methodParam) throws TypeMismatchException;
   @Nullable
   <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
         throws TypeMismatchException;
}

这个TypeConverter就是判断当前的转换器中能不能转换,能转换就调用对应方法进行转换:

public interface PropertyEditorRegistry {
   void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor);
   void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor);
   @Nullable
   PropertyEditor findCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath);
}

PropertyEditorRegistry ,通过参数就可以知道其是用来注册PropertyEditor 这种转换器的。

PropertyEditorRegistry 实现类PropertyEditorRegistrySupport:

public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
   @Nullable
   private ConversionService conversionService;
   private boolean defaultEditorsActive = false;
   private boolean configValueEditorsActive = false;
   @Nullable
   private Map<Class<?>, PropertyEditor> defaultEditors;
   @Nullable
   private Map<Class<?>, PropertyEditor> overriddenDefaultEditors;
   @Nullable
   private Map<Class<?>, PropertyEditor> customEditors;
   @Nullable
   private Map<String, CustomEditorHolder> customEditorsForPath;
   @Nullable
   private Map<Class<?>, PropertyEditor> customEditorCache;
 ................................
public PropertyEditor getDefaultEditor(Class<?> requiredType) {
   if (!this.defaultEditorsActive) {
      return null;
   }
   if (this.overriddenDefaultEditors != null) {
      PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType);
      if (editor != null) {
         return editor;
      }
   }
   if (this.defaultEditors == null) {
      createDefaultEditors();
   }
   return this.defaultEditors.get(requiredType);
}
private void createDefaultEditors() {
   this.defaultEditors = new HashMap<>(64);

   // Simple editors, without parameterization capabilities.
   // The JDK does not contain a default editor for any of these target types.
   this.defaultEditors.put(Charset.class, new CharsetEditor());
   this.defaultEditors.put(Class.class, new ClassEditor());
}
  ..............................
}

这里关注两种类型,defaultEditors这个就是Spring的默认添加的PropertyEditor,customEditors这个就是你自定义的propertyEditor是添加在这里,这里的ConversionService 就是赋值前面讲的用与管理GenericConverter类型转换的GenericConversionService及其子类

     再回到TypeConverterSupport:

public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport implements TypeConverter {
   @Nullable
   TypeConverterDelegate typeConverterDelegate;
   @Override
   @Nullable
   public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType) throws TypeMismatchException {
      return doConvert(value, requiredType, null, null);
   }
   @Override
   @Nullable
   public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable MethodParameter methodParam)
         throws TypeMismatchException {

      return doConvert(value, requiredType, methodParam, null);
   }
   @Override
   @Nullable
   public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType, @Nullable Field field)
         throws TypeMismatchException {

      return doConvert(value, requiredType, null, field);
   }
   @Nullable
   private <T> T doConvert(@Nullable Object value,@Nullable Class<T> requiredType,
         @Nullable MethodParameter methodParam, @Nullable Field field) throws TypeMismatchException {

      Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate");
      try {
         if (field != null) {
            return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
         }
         else {
            return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
         }
      }
      catch (ConverterNotFoundException | IllegalStateException ex) {
         throw new ConversionNotSupportedException(value, requiredType, ex);
      }
      catch (ConversionException | IllegalArgumentException ex) {
         throw new TypeMismatchException(value, requiredType, ex);
      }
   }
}

可以看到这里convertIfNecessary最终是调用doConvert去转换的,而doConvert是调用typeConverterDelegate的convertIfNecessary。    

class TypeConverterDelegate {
   private final PropertyEditorRegistrySupport propertyEditorRegistry;
   @Nullable
   private final Object targetObject;
public TypeConverterDelegate(PropertyEditorRegistrySupport propertyEditorRegistry) {
   this(propertyEditorRegistry, null);
}
 ...................
}

可以看到TypeConverterDelegate的初始化是需要PropertyEditorRegistrySupport,而TypeConverterSupport实现了该类,并且TypeConverterSupport是抽象类,所以TypeConverterDelegate初始化的时候是TypeConverterSupport的实现类传的this,用代码验证下:

protected AbstractNestablePropertyAccessor(boolean registerDefaultEditors) {
   if (registerDefaultEditors) {
      registerDefaultEditors();
   }
   this.typeConverterDelegate = new TypeConverterDelegate(this);
}
public class SimpleTypeConverter extends TypeConverterSupport {
   public SimpleTypeConverter() {
      this.typeConverterDelegate = new TypeConverterDelegate(this);
      registerDefaultEditors();
   }
}

AbstractNestablePropertyAccessor实现了TypeConverterSupport。所以这里得到了验证,就是将作为TypeConverterSupport成员的TypeConverterDelegate类的初始化传TypeConverterSupport本身。

我们看TypeConverterDelegate的convertIfNecessary方法:

public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue,
      @Nullable Class<T> requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException {

   // Custom editor for this type?
   PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);

   ConversionFailedException conversionAttemptEx = null;

   // No custom editor but custom ConversionService specified?
   ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
   if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
      TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
      if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
         try {
            return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
         }
         catch (ConversionFailedException ex) {
            // fallback to default conversion logic below
            conversionAttemptEx = ex;
         }
      }
   }
   Object convertedValue = newValue;
     ..................
   if (editor == null) {
      editor = findDefaultEditor(requiredType);
   }
   convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
}
   ...............(这后面有一串很长的代码,不过一般用前面这一串就可以完成转换了)

   return (T) convertedValue;
}

  1、这里实现是获取自定义PropertyEditor。

   2、如果ConversionService不为空,就是指如果存在Converter类型的转获取其,其这里找一下,看有没有符合的Converter转换器:

    conversionService.canConvert(sourceTypeDesc, typeDescriptor),该放在在GenericConversionService的实现:

public boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
      ...........
   GenericConverter converter = getConverter(sourceType, targetType);
   return (converter != null);
}
protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
   ConverterCacheKey key = new ConverterCacheKey(sourceType, targetType);
   GenericConverter converter = this.converterCache.get(key);
   if (converter != null) {
      return (converter != NO_MATCH ? converter : null);
   }
   converter = this.converters.find(sourceType, targetType);
   if (converter == null) {
      converter = getDefaultConverter(sourceType, targetType);
   }
   if (converter != null) {
      this.converterCache.put(key, converter);
      return converter;
   }
   this.converterCache.put(key, NO_MATCH);
   return null;
}

这里是用了缓存,我们找到在放到缓存前的两个方法:

converter = this.converters.find(sourceType, targetType);
if (converter == null) {
   converter = getDefaultConverter(sourceType, targetType);
}

这里的find方法在前面已经讲GenericConversionService的时候就讲了,我们看下如果没有获取到,调用getDefaultConverter:   

@Nullable
protected GenericConverter getDefaultConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
   return (sourceType.isAssignableTo(targetType) ? NO_OP_CONVERTER : null);
}
private static final GenericConverter NO_OP_CONVERTER = new NoOpConverter("NO_OP");
private static class NoOpConverter implements GenericConverter {
   private final String name;
   ..........
   @Nullable
   public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
      return source;
   }
}

我们再回到前面的convertIfNecessary,如果在这里找到了对应Converter类型的转换器,就去进行对应的转换:

public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
 ...............
   GenericConverter converter = getConverter(sourceType, targetType);
   if (converter != null) {
      Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
      return handleResult(sourceType, targetType, result);
   }
   ................
}

获取对应的GenericConverter,然后通过ConversionUtils工具类ConversionUtils去转换:

public static Object invokeConverter(GenericConverter converter, @Nullable Object source,
      TypeDescriptor sourceType, TypeDescriptor targetType) {

   try {
      return converter.convert(source, sourceType, targetType);
   }
   catch (ConversionFailedException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new ConversionFailedException(sourceType, targetType, source, ex);
   }
}

再回到convertIfNecessary方法,如果没有对应的GenericConverter类型转换器,就会接着往下:

if (editor == null) {
   editor = findDefaultEditor(requiredType);
}
convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);

如果没有自定义的PropertyEditor,就会获取默认的PropertyEditor,去转换:

private PropertyEditor findDefaultEditor(@Nullable Class<?> requiredType) {
   ..............
      editor = this.propertyEditorRegistry.getDefaultEditor(requiredType);
      ..........
   return editor;
}
这里就回到前面讲propertyEditorRegistrySupport是时候的getDefaultEditor方法了,将所有的默认Editer,添加到defaultEditors。

  自此,这个Spring的类型转换就梳理完毕了。Spring中如果要进行类型转换,就会持有TypeConverterDelegate,或者持有

TypeConverterSupport的子类。同时通过这个流程可以知道。进行类型转换的时候首先是使用Converter类型,如果该类型能完成转换,就不会去使用propertyEditor了。并且,在使用Converter类型的时候,是先使用实现ConditionalGenericConverter接口的类,如果没有才会再去使用实现ConditionalConverter类型的类。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值