Register converters and converterFactories with annotations in Spring 3

前端 未结 7 1419
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 21:11

First of all ... Im relatively new in Spring, I use spring 3.x and I DONT LIKE SPRING\'S XML CONFIGURATION FILES ... I dont want for every refactoring I do, to run into XML

相关标签:
7条回答
  • 2020-12-09 22:05

    Spring does not have annotation support for Converters, but you can build your own.

    All you need is an custom qualifier annotation (lets call it @AutoRegistered ) and some kind of Converter/Formatter Registrar (implements FormatterRegistrar) that registers all the Spring Beans with this @AutoRegistered annotation (and some xml to register this registration service).

    Then you need to annotate your conveter with this annotation (and some other annotation to make it a spring bean) and that is all.

    @AutoRegistered annotation:

    @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    public @interface AutoRegistered {}
    

    Registration service:

    import java.util.List;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.convert.converter.Converter;
    import org.springframework.format.FormatterRegistrar;
    import org.springframework.format.FormatterRegistry;
    
    public class AutoregisterFormatterRegistrar implements FormatterRegistrar {
    
        /**
         * All {@link Converter} Beans with {@link AutoRegistered} annotation.
         * If spring does not find any matching bean, then the List is {@code null}!.
         */
        @Autowired(required = false)
        @AutoRegistered
        private List<Converter<?, ?>> autoRegisteredConverters;
    
    
        @Override
        public void registerFormatters(final FormatterRegistry registry) {
            if (this.autoRegisteredConverters != null) {
                for (Converter<?, ?> converter : this.autoRegisteredConverters) {
                    registry.addConverter(converter);
                }
            }
        }
    }
    

    XML configuration for the registrar:

    <bean id="applicationConversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatterRegistrars">
            <set>
                <bean
                    class="AutoregisterFormatterRegistrar"
                    autowire="byType" />
            </set>
        </property>
    </bean>
    

    BTW for your enum converter you do not need a ConversionFactory - a simple converter is enough:

    @AutoRegistered
    @Component
    public class EnumConverter implements Converter<Enum<?>, String> {
    
        /** Use the same immutable value instead of creating an new array every time. */
        private static final Object[] NO_PARAM = new Object[0];
    
        /** The prefix of all message codes. */
        private static final String PREFIX = "label_";
    
        /** The separator in the message code, between different packages
            as well as between package can class. */
        private static final String PACKAGE_SEPARATOR = "_";
    
        /** The separator in the message code, between the class name
            and the enum case name. */
        private static final String ENUM_CASE_SEPARATOR = "_";
    
        /** The message source. */
        private MessageSource messageSource;
    
        @Autowired
        public EnumConverter(final MessageSource messageSource) {
            if (messageSource == null) {
                throw new RuntimeException("messageSource must not be null");
            }
    
            this.messageSource = messageSource;
        }
    
        @Override
        public String convert(final Enum<?> source) {
            if (source != null) {
                String enumValueName = source.name();
                String code = PREFIX + source.getClass().getName().toLowerCase().
                      replace(".", PACKAGE_SEPARATOR)
                + ENUM_CASE_SEPARATOR + enumValueName.toLowerCase();
    
                String message = messageSource.getMessage(code, NO_PARAM, enumValueName,
                                                      LocaleContextHolder.getLocale());
    
                 return message;
             } else {
                return "";
             }
         }   
    }
    
    0 讨论(0)
提交回复
热议问题