在 Spring 3 中使用注解注册转换器和转换器工厂 [英] Register converters and converterFactories with annotations in Spring 3

查看:40
本文介绍了在 Spring 3 中使用注解注册转换器和转换器工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先......我在 Spring 中相对较新,我使用 spring 3.x 并且我不喜欢 SPRING 的 XML 配置文件......我不希望我所做的每次重构都遇到 XML 文件进行更新...

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 file for updates ...

我正在尝试以一种方式配置 spring,对于任何请求,如果我的 hadlers 中有一些 @RequestParam/@RequestBody/@PathVariable 等类型不是 String,则 spring 会将值正确转换为该类型或放置null 到处理程序的参数(我从不在处理程序参数中使用原始类型).到目前为止一切顺利......

I'm trying to configure spring in a way that for any request, if I have some @RequestParam/@RequestBody/@PathVariable etc with type other than String in my hadlers, spring will convert values to that type correctly or put null to handler's args (I never use primitive types in handler arguments). So far so good ...

到目前为止,我已经注册了所有的转换器/转换器工厂类,如下所示:

Until now I've registered all converter/converterFactory classes like this:

 <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
     <property name="converters">
         <list>
             <!-- converters is a set of both converters and converterfactories -->
             <bean class="controller.converters.enumConverter" />
             <bean class="controller.converters.integerConverter" />
             <bean class="controller.converters.objects.FooConverter" />
             ...
         </list>
     </property>
 </bean>

有没有办法用注解注册转换器?

Is there any way to register converters with annotations?

关于 spring XML 的任何事情(或只是基本的东西)都可以仅使用注释来完成,并且一劳永逸地摆脱 XML 配置吗?...以及如何?

Can anything (or just basic stuff) about spring XML be done with annotations only, and get rid of XML configuration once and for all? ... and how?

推荐答案

Spring 没有对转换器的注解支持,但您可以构建自己的.

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

您只需要一个自定义限定符注释(我们称之为 @AutoRegistered )和某种转换器/格式器注册器(实现 FormatterRegistrar) 使用此 注册所有 Spring Bean@AutoRegistered 注释(以及一些用于注册此注册服务的 xml).

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 注释:

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

注册服务:

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 配置:

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>

顺便说一句,对于您的枚举转换器,您不需要 ConversionFactory - 一个简单的转换器就足够了:

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

这篇关于在 Spring 3 中使用注解注册转换器和转换器工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆