@ -72,9 +72,9 @@ When you need to centralize the conversion logic for an entire class hierarchy
@@ -72,9 +72,9 @@ When you need to centralize the conversion logic for an entire class hierarchy
}
----
Parameterize S to be the type you are converting from and R to be the base type defining
Parameterize `S` to be the type you are converting from and `R` to be the base type defining
the __range__ of classes you can convert to. Then implement `getConverter(Class<T>)`,
where T is a subclass of R.
where `T` is a subclass of `R`.
Consider the `StringToEnumConverterFactory` as an example:
@ -107,13 +107,15 @@ Consider the `StringToEnumConverterFactory` as an example:
@@ -107,13 +107,15 @@ Consider the `StringToEnumConverterFactory` as an example:
[[core-convert-GenericConverter-SPI]]
== Using `GenericConverter`
When you require a sophisticated `Converter` implementation, consider using the
`GenericConverter` interface. With a more flexible but less strongly typed signature
than `Converter`, a `GenericConverter` supports converting between multiple source and
target types. In addition, a `GenericConverter` makes available source and target field
context that you can use when you implement your conversion logic. Such context lets a
type conversion be driven by a field annotation or by generic information declared on a
field signature. The following listing shows the interface definition of `GenericConverter`:
When you require a more sophisticated `Converter` implementation, consider using the
`GenericConverter` interface. With a more flexible but less strongly typed signature than
`Converter`, a `GenericConverter` supports converting between multiple source and target
types. In addition, a `GenericConverter` is provided source and target type descriptors
that you can use when you implement your conversion logic. Such type descriptors enable
type conversion to be driven by an annotation on the source of the descriptor (such as a
field or method) or by generic information declared in a field signature, method
signature, etc. The following listing shows the definition of the `GenericConverter`
@ -128,16 +130,17 @@ field signature. The following listing shows the interface definition of `Generi
@@ -128,16 +130,17 @@ field signature. The following listing shows the interface definition of `Generi
----
To implement a `GenericConverter`, have `getConvertibleTypes()` return the supported
source->target type pairs. Then implement `convert(Object, TypeDescriptor,
source → target type pairs. Then implement `convert(Object, TypeDescriptor,
TypeDescriptor)` to contain your conversion logic. The source `TypeDescriptor` provides
access to the source field that holds the value being converted. The target `TypeDescriptor`
provides access to the target field where the converted value is to be set.
access to the source field or method that holds the value being converted. The target
`TypeDescriptor` provides access to the target field or method where the converted value
is to be set.
A good example of a `GenericConverter` is a converter that converts between a Java array
and a collection. Such an `ArrayToCollectionConverter` introspects the field that declares
the target collection type to resolve the collection's element type. This lets each
element in the source array be converted to the collection element type before the
collection is set on the target field.
and a collection. Such an `ArrayToCollectionConverter` introspects the field or method
that declares the target collection type to resolve the collection's element type. This
lets each element in the source array be converted to the collection element type before
the collection is set on the target field or supplied to the target method or constructor.
NOTE: Because `GenericConverter` is a more complex SPI interface, you should use
it only when you need it. Favor `Converter` or `ConverterFactory` for basic type
Sometimes, you want a `Converter` to run only if a specific condition holds true. For
example, you might want to run a `Converter` only if a specific annotation is present
on the target field, or you might want to run a `Converter` only if a specific method
(such as a `static valueOf` method) is defined on the target class.
example, you might want to run a `Converter` only if a specific annotation is present on
the target field or method, or you might want to run a `Converter` only if a specific
method (such as a `static valueOf` method) is defined on the target type.
`ConditionalGenericConverter` is the union of the `GenericConverter` and
`ConditionalConverter` interfaces that lets you define such custom matching criteria:
@ -212,7 +215,7 @@ creating common `ConversionService` configurations.
@@ -212,7 +215,7 @@ creating common `ConversionService` configurations.
A `ConversionService` is a stateless object designed to be instantiated at application
startup and then shared between multiple threads. In a Spring application, you typically
configure a `ConversionService` instance for each Spring container (or `ApplicationContext`).
Spring picks up that `ConversionService` and uses it whenever a type
Spring picks up that `ConversionService` and uses it whenever type
conversion needs to be performed by the framework. You can also inject this
`ConversionService` into any of your beans and invoke it directly.
@ -249,7 +252,8 @@ It is also common to use a `ConversionService` within a Spring MVC application.
@@ -249,7 +252,8 @@ It is also common to use a `ConversionService` within a Spring MVC application.
xref:web/webmvc/mvc-config/conversion.adoc[Conversion and Formatting] in the Spring MVC chapter.
In certain situations, you may wish to apply formatting during conversion. See
xref:core/validation/format.adoc#format-FormatterRegistry-SPI[The `FormatterRegistry` SPI] for details on using `FormattingConversionServiceFactoryBean`.