Spring ConversionService adding Converters

后端 未结 9 723
别那么骄傲
别那么骄傲 2020-12-31 03:47

I searched for the below problem, but couldn\'t find an answer.

I want to use spring\'s conversion service by writing my custom converter that implements org.spri

相关标签:
9条回答
  • 2020-12-31 04:31

    It's enough to override the ConversionServiceFactoryBean.afterPropertiesSet() and set the ConversionService object to your converters there. Let your converters implement some interface that allows to set a ConversionService object, say ConversionServiceAware. The only problem is to get access to the registered converters, so you'll also have to override the 'setConverters()' method.

    public class MyFormattingConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean {
    
        private Set<?> cachedConverters = new LinkedHashSet<>();
    
        @Override
        public void setConverters(Set<?> converters) {
            super.setConverters(converters);
            this.cachedConverters = new LinkedHashSet<>(converters);
    
        }
    
        @Override
        public void afterPropertiesSet() {
            super.afterPropertiesSet();
            FormattingConversionService conversionService = getObject();
            for (Object converter : cachedConverters) {
                if (converter instanceof ConversionServiceAware) {
                    ((ConversionServiceAware) converter).setConversionService(conversionService);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-31 04:31

    This variant works for me. If you use java configuration, you can add your converters to existing GenericConversionService

    https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html

    Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container. Bean property setter methods are effectively just a special case of such a general config method. Such config methods do not have to be public.
    
        @Configuration
        class MyConfig {
    
        @Autowired
        void conversionService(GenericConversionService genericConversionService) {
            genericConversionService.addConverter(String.class, UUID.class, UUID::fromString);
            genericConversionService.addConverter(String.class, DateTime.class, DateTime::parse);
            genericConversionService.addConverter(String.class, EnumState.class, EnumState::valueOf);
        }
    }
    
    0 讨论(0)
  • 2020-12-31 04:32

    You can also add it dinamically using addConverter method on your DefaultConversionService-ish class:

    DefaultConversionService cs = new <YourClassThatInheritsFromDefaultConversionService or DefaultConversionService>();
    
    cs.addConverter(new MyConverter());
    
    0 讨论(0)
  • 2020-12-31 04:34

    For anyone who stumbles on this now via a google search or similar 2+ years after the question was originally posted, adding converters has been made much easier through Java Config: WebMvcConfigurerAdapter provides the addFormatters(FormatterRegistry) method that can be used to specify additional custom converters.

    0 讨论(0)
  • 2020-12-31 04:38

    While experimenting with different ways and even following spring source code in some i came across with an interesting thing.

    The only way i found to use conversionService without overriding the existing converters with my custom ones was either to extend or re-implement the conversionService calling the super class's afterPropertiesSet() method to register the default converters and then add the custom ones.

    But even if i was using that way, at runtime i was getting an exception that no converter was found for my specific types (e.g. from String to Logger).

    That triggered my interest and i followed spring source code to find out why and i realized that spring was trying to find a custom converter registered with PropertyEditor. I am not sure why this is happening. I have to add here that my application is not using spring mvc and conversionService might somehow need to be registered and i didn't do it.

    Finally, i solved the issue with registering a custom converter using Property editor. This documentation can be viewed as reference:

    http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html

    I would be very interested in knowing why Spring was not finding my registered custom converters in the conversionService's registry (or at least why spring was not looking at that registry to find the custom converters). Was i missing any configuration?

    0 讨论(0)
  • 2020-12-31 04:39

    With spring > 4 it is no more necessary to implement an own derivation of the ConversionService. Initialize it in a @Configuration annotated class as follows:

    @Configuration
    public class ConversionServiceProvider
    {
        @Autowired
        private MyConverterImpl myConverter;
    
        @Bean
        public ConversionService getConversionService()
        {
            ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
            bean.setConverters( getConverters() );
            bean.afterPropertiesSet();
            ConversionService object = bean.getObject();
            return object;
        }
    
        private Set<Converter<?, ?>> getConverters()
        {
            Set<Converter<?, ?>> converters = new HashSet<Converter<?, ?>>();
    
            converters.add( myConverter );
            // add here more custom converters, either as spring bean references or directly instantiated
    
            return converters;
        }
    }
    
    0 讨论(0)
提交回复
热议问题