Spring には、コンバーターの注釈サポートはありませんが、独自に構築できます。
必要なのは、カスタム修飾子アノテーション ( let と呼びます) と、すべての Spring Bean をこのアノテーション (およびこの登録サービスを登録するための xml ) に@AutoRegistered
登録するある種のコンバーター/フォーマッター レジストラー (implements ) だけです。FormatterRegistrar
@AutoRegistered
次に、この注釈 (およびそれを Spring Bean にするための他の注釈) でコンベターに注釈を付ける必要があり、それだけです。
@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 構成:
<bean id="applicationConversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatterRegistrars">
<set>
<bean
class="AutoregisterFormatterRegistrar"
autowire="byType" />
</set>
</property>
</bean>
ところで、列挙型コンバーターは必要ありませんConversionFactory
-単純なコンバーターで十分です:
@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 "";
}
}
}