As compare to org.springframework.core.convert.converter.Converter interface, org.springframework.core.convert.converter.GenericConverter interface is less strongly typed converter.
Definition of GenericConverter(Version: spring-framework 6.1.2) package org.springframework.core.convert.converter;
........
public interface GenericConverter {
@Nullable
Set<ConvertiblePair> getConvertibleTypes(); 1
@Nullable
Object convert(
@Nullable Object source,
TypeDescriptor sourceType,
TypeDescriptor targetType); 2
........
}
As GenericConverter may support converting between multiple source/target type pairs, it is considered to be flexible as compared to org.springframework.core.convert.converter.Converter .
The disadvantage of using GenericConverter is that it can get very complex because of it's flexibility.
Example
In following simple example we are going to create a GenericConverter for Number to BigDecimal conversion.
package com.logicbig.example;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Set;
public class NumberToBigDecimalConverter implements GenericConverter {
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Number.class,
BigDecimal.class));
}
@Override
public Object convert(Object source, TypeDescriptor sourceType,
TypeDescriptor targetType) {
if (sourceType.getType() == BigDecimal.class) {
return source;
}
Number number = (Number) source;
return new BigDecimal(number.doubleValue());
}
}
package com.logicbig.example;
import org.springframework.core.convert.support.DefaultConversionService;
import java.math.BigDecimal;
public class GenericConverterExample {
public static void main (String[] args) {
DefaultConversionService service = new DefaultConversionService();
service.addConverter(new NumberToBigDecimalConverter());
BigDecimal bd = service.convert(Double.valueOf("2222.336"),
BigDecimal.class);
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(bd);
}
}
Output2222.34
Built-in generic converters
Following code list all built-in GenericConverter classes:
package com.logicbig.example;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import java.util.Set;
public class SpringBuiltInGenericConvertersFinder {
public static void main(String[] args) {
ClassPathScanningCandidateComponentProvider provider =
new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(GenericConverter.class));
provider.addExcludeFilter(new AssignableTypeFilter(ConditionalGenericConverter.class));
Set<BeanDefinition> components = provider.findCandidateComponents("org/springframework");
components.stream()
.map(BeanDefinition::getBeanClassName)
.forEach(System.out::println);
}
}
Outputorg.springframework.format.support.FormattingConversionService$PrinterConverter org.springframework.format.support.FormattingConversionService$ParserConverter org.springframework.core.convert.support.GenericConversionService$NoOpConverter
In above code we have excluded ConditionalGenericConverter which is a sub-interface of GenericConverter (next tutorial)
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 4.0.7.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|