类org.springframework.core.convert.converter.GenericConverter源码实例Demo

下面列出了怎么用org.springframework.core.convert.converter.GenericConverter的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: sdn-rx   文件: Neo4jMappingContextTest.java
@Test
void complexPropertyWithConverterShouldNotBeConsideredAsAssociation() {

	class ConvertibleTypeConverter implements GenericConverter {
		@Override
		public Set<ConvertiblePair> getConvertibleTypes() {
			// in the real world this should also define the opposite way
			return singleton(new ConvertiblePair(ConvertibleType.class, StringValue.class));
		}

		@Override
		public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
			// no implementation needed for this test
			return null;
		}
	}

	Neo4jMappingContext schema = new Neo4jMappingContext(
		new Neo4jConversions(singleton(new ConvertibleTypeConverter())));
	Neo4jPersistentEntity<?> entity = schema.getPersistentEntity(EntityWithConvertibleProperty.class);

	assertThat(entity.getPersistentProperty("convertibleType").isRelationship()).isFalse();
}
 
@Override
@SuppressWarnings("unchecked")
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = sourceType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + sourceType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, sourceType.getObjectType());
	GenericConverter converter = cachedPrinters.get(converterKey);
	if (converter == null) {
		Printer<?> printer = this.annotationFormatterFactory.getPrinter(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new PrinterConverter(this.fieldType, printer, FormattingConversionService.this);
		cachedPrinters.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
@Override
@SuppressWarnings("unchecked")
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = targetType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + targetType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, targetType.getObjectType());
	GenericConverter converter = cachedParsers.get(converterKey);
	if (converter == null) {
		Parser<?> parser = this.annotationFormatterFactory.getParser(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new ParserConverter(this.fieldType, parser, FormattingConversionService.this);
		cachedParsers.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
/**
 * Register the given Converter objects with the given target ConverterRegistry.
 * @param converters the converter objects: implementing {@link Converter},
 * {@link ConverterFactory}, or {@link GenericConverter}
 * @param registry the target registry
 */
public static void registerConverters(@Nullable Set<?> converters, ConverterRegistry registry) {
	if (converters != null) {
		for (Object converter : converters) {
			if (converter instanceof GenericConverter) {
				registry.addConverter((GenericConverter) converter);
			}
			else if (converter instanceof Converter<?, ?>) {
				registry.addConverter((Converter<?, ?>) converter);
			}
			else if (converter instanceof ConverterFactory<?, ?>) {
				registry.addConverterFactory((ConverterFactory<?, ?>) converter);
			}
			else {
				throw new IllegalArgumentException("Each converter object must implement one of the " +
						"Converter, ConverterFactory, or GenericConverter interfaces");
			}
		}
	}
}
 
@Override
@Nullable
public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
	Assert.notNull(targetType, "Target type to convert to cannot be null");
	if (sourceType == null) {
		Assert.isTrue(source == null, "Source must be [null] if source type == [null]");
		return handleResult(null, targetType, convertNullSource(null, targetType));
	}
	if (source != null && !sourceType.getObjectType().isInstance(source)) {
		throw new IllegalArgumentException("Source to convert from must be an instance of [" +
				sourceType + "]; instead it was a [" + source.getClass().getName() + "]");
	}
	GenericConverter converter = getConverter(sourceType, targetType);
	if (converter != null) {
		Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
		return handleResult(sourceType, targetType, result);
	}
	return handleConverterNotFound(source, sourceType, targetType);
}
 
/**
 * Hook method to lookup the converter for a given sourceType/targetType pair.
 * First queries this ConversionService's converter cache.
 * On a cache miss, then performs an exhaustive search for a matching converter.
 * If no converter matches, returns the default converter.
 * @param sourceType the source type to convert from
 * @param targetType the target type to convert to
 * @return the generic converter that will perform the conversion,
 * or {@code null} if no suitable converter was found
 * @see #getDefaultConverter(TypeDescriptor, TypeDescriptor)
 */
@Nullable
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;
}
 
/**
 * Find a {@link GenericConverter} given a source and target type.
 * <p>This method will attempt to match all possible converters by working
 * through the class and interface hierarchy of the types.
 * @param sourceType the source type
 * @param targetType the target type
 * @return a matching {@link GenericConverter}, or {@code null} if none found
 */
@Nullable
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
	// Search the full type hierarchy
	List<Class<?>> sourceCandidates = getClassHierarchy(sourceType.getType());
	List<Class<?>> targetCandidates = getClassHierarchy(targetType.getType());
	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;
}
 
@Nullable
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;
}
 
源代码9 项目: spring-data-crate   文件: CustomConversions.java
/**
 * Inspects the given {@link org.springframework.core.convert.converter.GenericConverter.ConvertiblePair} for ones
 * that have a source compatible type as source. Additionally checks assignability of the target type if one is
 * given.
 *
 * @param sourceType must not be {@literal null}.
 * @param requestedTargetType can be {@literal null}.
 * @param pairs must not be {@literal null}.
 * @return
 */
private static Class<?> getCustomTarget(Class<?> sourceType, Class<?> requestedTargetType,
  Iterable<GenericConverter.ConvertiblePair> pairs) {
  notNull(sourceType);
  notNull(pairs);

  for (GenericConverter.ConvertiblePair typePair : pairs) {
    if (typePair.getSourceType().isAssignableFrom(sourceType)) {
      Class<?> targetType = typePair.getTargetType();
      if (requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType)) {
        return targetType;
      }
    }
  }

  return null;
}
 
@Override
@SuppressWarnings("unchecked")
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = sourceType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + sourceType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, sourceType.getObjectType());
	GenericConverter converter = cachedPrinters.get(converterKey);
	if (converter == null) {
		Printer<?> printer = this.annotationFormatterFactory.getPrinter(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new PrinterConverter(this.fieldType, printer, FormattingConversionService.this);
		cachedPrinters.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
@Override
@SuppressWarnings("unchecked")
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = targetType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + targetType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, targetType.getObjectType());
	GenericConverter converter = cachedParsers.get(converterKey);
	if (converter == null) {
		Parser<?> parser = this.annotationFormatterFactory.getParser(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new ParserConverter(this.fieldType, parser, FormattingConversionService.this);
		cachedParsers.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
/**
 * Register the given Converter objects with the given target ConverterRegistry.
 * @param converters the converter objects: implementing {@link Converter},
 * {@link ConverterFactory}, or {@link GenericConverter}
 * @param registry the target registry
 */
public static void registerConverters(@Nullable Set<?> converters, ConverterRegistry registry) {
	if (converters != null) {
		for (Object converter : converters) {
			if (converter instanceof GenericConverter) {
				registry.addConverter((GenericConverter) converter);
			}
			else if (converter instanceof Converter<?, ?>) {
				registry.addConverter((Converter<?, ?>) converter);
			}
			else if (converter instanceof ConverterFactory<?, ?>) {
				registry.addConverterFactory((ConverterFactory<?, ?>) converter);
			}
			else {
				throw new IllegalArgumentException("Each converter object must implement one of the " +
						"Converter, ConverterFactory, or GenericConverter interfaces");
			}
		}
	}
}
 
@Override
@Nullable
public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
	Assert.notNull(targetType, "Target type to convert to cannot be null");
	if (sourceType == null) {
		Assert.isTrue(source == null, "Source must be [null] if source type == [null]");
		return handleResult(null, targetType, convertNullSource(null, targetType));
	}
	if (source != null && !sourceType.getObjectType().isInstance(source)) {
		throw new IllegalArgumentException("Source to convert from must be an instance of [" +
				sourceType + "]; instead it was a [" + source.getClass().getName() + "]");
	}
	GenericConverter converter = getConverter(sourceType, targetType);
	if (converter != null) {
		Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
		return handleResult(sourceType, targetType, result);
	}
	return handleConverterNotFound(source, sourceType, targetType);
}
 
/**
 * Hook method to lookup the converter for a given sourceType/targetType pair.
 * First queries this ConversionService's converter cache.
 * On a cache miss, then performs an exhaustive search for a matching converter.
 * If no converter matches, returns the default converter.
 * @param sourceType the source type to convert from
 * @param targetType the target type to convert to
 * @return the generic converter that will perform the conversion,
 * or {@code null} if no suitable converter was found
 * @see #getDefaultConverter(TypeDescriptor, TypeDescriptor)
 */
@Nullable
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;
}
 
/**
 * Find a {@link GenericConverter} given a source and target type.
 * <p>This method will attempt to match all possible converters by working
 * through the class and interface hierarchy of the types.
 * @param sourceType the source type
 * @param targetType the target type
 * @return a matching {@link GenericConverter}, or {@code null} if none found
 */
@Nullable
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
	// Search the full type hierarchy
	List<Class<?>> sourceCandidates = getClassHierarchy(sourceType.getType());
	List<Class<?>> targetCandidates = getClassHierarchy(targetType.getType());
	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;
}
 
@Nullable
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;
}
 
源代码17 项目: lams   文件: FormattingConversionService.java
@Override
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = sourceType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + sourceType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, sourceType.getObjectType());
	GenericConverter converter = cachedPrinters.get(converterKey);
	if (converter == null) {
		Printer<?> printer = this.annotationFormatterFactory.getPrinter(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new PrinterConverter(this.fieldType, printer, FormattingConversionService.this);
		cachedPrinters.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
源代码18 项目: lams   文件: FormattingConversionService.java
@Override
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = targetType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + targetType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, targetType.getObjectType());
	GenericConverter converter = cachedParsers.get(converterKey);
	if (converter == null) {
		Parser<?> parser = this.annotationFormatterFactory.getParser(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new ParserConverter(this.fieldType, parser, FormattingConversionService.this);
		cachedParsers.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
源代码19 项目: lams   文件: ConversionServiceFactory.java
/**
 * Register the given Converter objects with the given target ConverterRegistry.
 * @param converters the converter objects: implementing {@link Converter},
 * {@link ConverterFactory}, or {@link GenericConverter}
 * @param registry the target registry
 */
public static void registerConverters(Set<?> converters, ConverterRegistry registry) {
	if (converters != null) {
		for (Object converter : converters) {
			if (converter instanceof GenericConverter) {
				registry.addConverter((GenericConverter) converter);
			}
			else if (converter instanceof Converter<?, ?>) {
				registry.addConverter((Converter<?, ?>) converter);
			}
			else if (converter instanceof ConverterFactory<?, ?>) {
				registry.addConverterFactory((ConverterFactory<?, ?>) converter);
			}
			else {
				throw new IllegalArgumentException("Each converter object must implement one of the " +
						"Converter, ConverterFactory, or GenericConverter interfaces");
			}
		}
	}
}
 
源代码20 项目: lams   文件: GenericConversionService.java
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Assert.notNull(targetType, "Target type to convert to cannot be null");
	if (sourceType == null) {
		Assert.isTrue(source == null, "Source must be [null] if source type == [null]");
		return handleResult(null, targetType, convertNullSource(null, targetType));
	}
	if (source != null && !sourceType.getObjectType().isInstance(source)) {
		throw new IllegalArgumentException("Source to convert from must be an instance of [" +
				sourceType + "]; instead it was a [" + source.getClass().getName() + "]");
	}
	GenericConverter converter = getConverter(sourceType, targetType);
	if (converter != null) {
		Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
		return handleResult(sourceType, targetType, result);
	}
	return handleConverterNotFound(source, sourceType, targetType);
}
 
源代码21 项目: lams   文件: GenericConversionService.java
/**
 * Hook method to lookup the converter for a given sourceType/targetType pair.
 * First queries this ConversionService's converter cache.
 * On a cache miss, then performs an exhaustive search for a matching converter.
 * If no converter matches, returns the default converter.
 * @param sourceType the source type to convert from
 * @param targetType the target type to convert to
 * @return the generic converter that will perform the conversion,
 * or {@code null} if no suitable converter was found
 * @see #getDefaultConverter(TypeDescriptor, TypeDescriptor)
 */
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;
}
 
源代码22 项目: lams   文件: GenericConversionService.java
/**
 * Find a {@link GenericConverter} given a source and target type.
 * <p>This method will attempt to match all possible converters by working
 * through the class and interface hierarchy of the types.
 * @param sourceType the source type
 * @param targetType the target type
 * @return a matching {@link GenericConverter}, or {@code null} if none found
 */
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
	// Search the full type hierarchy
	List<Class<?>> sourceCandidates = getClassHierarchy(sourceType.getType());
	List<Class<?>> targetCandidates = getClassHierarchy(targetType.getType());
	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;
}
 
源代码23 项目: lams   文件: GenericConversionService.java
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;
}
 
源代码24 项目: dubbox   文件: CustomConversions.java
/**
 * Register custom converters within given
 * {@link org.springframework.core.convert.support.GenericConversionService}
 *
 * @param conversionService
 *            must not be null
 */
public void registerConvertersIn(GenericConversionService conversionService) {
	Assert.notNull(conversionService);

	for (Object converter : converters) {
		if (converter instanceof Converter) {
			conversionService.addConverter((Converter<?, ?>) converter);
		} else if (converter instanceof ConverterFactory) {
			conversionService.addConverterFactory((ConverterFactory<?, ?>) converter);
		} else if (converter instanceof GenericConverter) {
			conversionService.addConverter((GenericConverter) converter);
		} else {
			throw new IllegalArgumentException("Given object '" + converter
					+ "' expected to be a Converter, ConverterFactory or GenericeConverter!");
		}
	}
}
 
源代码25 项目: dubbox   文件: CustomConversions.java
private void registerConversion(Object converter) {
	Class<?> type = converter.getClass();
	boolean isWriting = type.isAnnotationPresent(WritingConverter.class);
	boolean isReading = type.isAnnotationPresent(ReadingConverter.class);

	if (!isReading && !isWriting) {
		isReading = true;
		isWriting = true;
	}

	if (converter instanceof GenericConverter) {
		GenericConverter genericConverter = (GenericConverter) converter;
		for (ConvertiblePair pair : genericConverter.getConvertibleTypes()) {
			register(new ConvertibleContext(pair, isReading, isWriting));
		}
	} else if (converter instanceof Converter) {
		Class<?>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class);
		register(new ConvertibleContext(arguments[0], arguments[1], isReading, isWriting));
	} else {
		throw new IllegalArgumentException(
				"Unsupported Converter type! Expected either GenericConverter if Converter.");
	}
}
 
@Override
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = sourceType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + sourceType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, sourceType.getObjectType());
	GenericConverter converter = cachedPrinters.get(converterKey);
	if (converter == null) {
		Printer<?> printer = this.annotationFormatterFactory.getPrinter(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new PrinterConverter(this.fieldType, printer, FormattingConversionService.this);
		cachedPrinters.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
@Override
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Annotation ann = targetType.getAnnotation(this.annotationType);
	if (ann == null) {
		throw new IllegalStateException(
				"Expected [" + this.annotationType.getName() + "] to be present on " + targetType);
	}
	AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, targetType.getObjectType());
	GenericConverter converter = cachedParsers.get(converterKey);
	if (converter == null) {
		Parser<?> parser = this.annotationFormatterFactory.getParser(
				converterKey.getAnnotation(), converterKey.getFieldType());
		converter = new ParserConverter(this.fieldType, parser, FormattingConversionService.this);
		cachedParsers.put(converterKey, converter);
	}
	return converter.convert(source, sourceType, targetType);
}
 
/**
 * Register the given Converter objects with the given target ConverterRegistry.
 * @param converters the converter objects: implementing {@link Converter},
 * {@link ConverterFactory}, or {@link GenericConverter}
 * @param registry the target registry
 */
public static void registerConverters(Set<?> converters, ConverterRegistry registry) {
	if (converters != null) {
		for (Object converter : converters) {
			if (converter instanceof GenericConverter) {
				registry.addConverter((GenericConverter) converter);
			}
			else if (converter instanceof Converter<?, ?>) {
				registry.addConverter((Converter<?, ?>) converter);
			}
			else if (converter instanceof ConverterFactory<?, ?>) {
				registry.addConverterFactory((ConverterFactory<?, ?>) converter);
			}
			else {
				throw new IllegalArgumentException("Each converter object must implement one of the " +
						"Converter, ConverterFactory, or GenericConverter interfaces");
			}
		}
	}
}
 
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
	Assert.notNull(targetType, "targetType to convert to cannot be null");
	if (sourceType == null) {
		Assert.isTrue(source == null, "source must be [null] if sourceType == [null]");
		return handleResult(null, targetType, convertNullSource(null, targetType));
	}
	if (source != null && !sourceType.getObjectType().isInstance(source)) {
		throw new IllegalArgumentException("source to convert from must be an instance of " +
				sourceType + "; instead it was a " + source.getClass().getName());
	}
	GenericConverter converter = getConverter(sourceType, targetType);
	if (converter != null) {
		Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
		return handleResult(sourceType, targetType, result);
	}
	return handleConverterNotFound(source, sourceType, targetType);
}
 
/**
 * Hook method to lookup the converter for a given sourceType/targetType pair.
 * First queries this ConversionService's converter cache.
 * On a cache miss, then performs an exhaustive search for a matching converter.
 * If no converter matches, returns the default converter.
 * @param sourceType the source type to convert from
 * @param targetType the target type to convert to
 * @return the generic converter that will perform the conversion,
 * or {@code null} if no suitable converter was found
 * @see #getDefaultConverter(TypeDescriptor, TypeDescriptor)
 */
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;
}
 
 类所在包
 同包方法