Close

Spring - Generic Converter

[Last Updated: Dec 22, 2023]

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
       ........
}
1Returns pairs of source-target types which this converter can convert between.
2Converts the source object to the targetType described by the TypeDescriptor. Returns the converted object.

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

Output

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

Output

org.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 Project

Dependencies and Technologies Used:

  • spring-context 6.1.2 (Spring Context)
     Version Compatibility: 4.0.7.RELEASE - 6.1.2Version List
    ×

    Version compatibilities of spring-context with this example:

    • 4.0.7.RELEASE
    • 4.0.8.RELEASE
    • 4.0.9.RELEASE
    • 4.1.0.RELEASE
    • 4.1.1.RELEASE
    • 4.1.2.RELEASE
    • 4.1.3.RELEASE
    • 4.1.4.RELEASE
    • 4.1.5.RELEASE
    • 4.1.6.RELEASE
    • 4.1.7.RELEASE
    • 4.1.8.RELEASE
    • 4.1.9.RELEASE
    • 4.2.0.RELEASE
    • 4.2.1.RELEASE
    • 4.2.2.RELEASE
    • 4.2.3.RELEASE
    • 4.2.4.RELEASE
    • 4.2.5.RELEASE
    • 4.2.6.RELEASE
    • 4.2.7.RELEASE
    • 4.2.8.RELEASE
    • 4.2.9.RELEASE
    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.1.0
    • 6.1.1
    • 6.1.2

    Versions in green have been tested.

  • JDK 17
  • Maven 3.8.1

Spring - Generic Converter Example Select All Download
  • spring-custom-generic-converter-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • NumberToBigDecimalConverter.java

    See Also