Ответ 1
Я бы сказал, что вы пытаетесь решить неправильную проблему. Я обычно сохраняю перечисления как строки и тем самым избегаю этой проблемы в первую очередь. Недостатком является, конечно, большее поле БД, но это вряд ли имеет значение.
Это сказало:
Я бы сказал, что это возможно вообще, но не в чистом виде. Что бы я сделал, это позволить всем этим перечислениям реализовать общий интерфейс (либо просто интерфейс маркера, либо тот, который содержит метод int getId()
). Теперь зарегистрируйте свой PropertyEditor только для этого интерфейса, тогда вы не нарушаете слишком много стандартных функций.
Затем ваша следующая проблема заключается в том, что вы полагаетесь на статические методы factory, которые нельзя выполнить общим способом. Конечно, ваш PropertyEditor может сделать:
enumClass.getDeclaredMethod("withId", int.class).invoke(id)
но я бы назвал это очень хаки. Как насчет чего-то подобного:
Object target = null;
for(Object e : EnumSet.allOf(yourEnumClass)){
if(e instanceof MyInterface && ((MyInterface)e).getId()==thisId){
target = e;
break;
}
}
return target;
Теперь вы не используете какие-либо статические методы factory, и у вас есть безопасность времени компиляции, если ваши перечисления реализуют общий интерфейс.
Обновление: с новым SPI конвертера становится проще. Используйте пользовательский ConverterFactory:
public class CustomEnumConverterFactory implements
ConverterFactory<String, Enum<?>>{
@Override
public <T extends Enum<?>> Converter<String, T> getConverter(
final Class<T> targetType){
return WithId.class.isAssignableFrom(targetType)
? new EnumWithIdConverter(targetType)
: new StandardEnumConverter(targetType);
}
}
Зарегистрируйте его следующим образом:
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<!-- converters is a set of both converters and converterfactories -->
<bean class="foo.bar.CustomEnumConverterFactory" />
</property>
</bean>