Spring泛型(参数化类型)转换服务?

问题描述 投票:0回答:2

我正在尝试为 Spring 创建一个通用转换器,它将允许传入的枚举值混合大小写并在映射到枚举之前转换为Upper。

当为特定枚举类型定义转换器时,该转换适用于我们使用的任何特定枚举类型。然而,当我将其编写为通用 Spring 时,它永远不会调用该代码。

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

// Doesn't work, Spring doesn't appear to allow Converters with type parameters :-(
@Component
public class StringToEnumConverter <T extends Enum> implements Converter<String, T> {

    @Override
    public T convert(String string) {
        Type type = ((ParameterizedType)StringToEnumConverter.class.getGenericSuperclass()).getActualTypeArguments()[0];
        return (T) Enum.valueOf((Class<T>)type, string.trim().toUpperCase());
    }
}

是代码不正确还是Spring在运行时不知道如何匹配类型?我希望

T extends Enum
足以让 Spring 通过这里发送所有 Enum 子类。

java spring
2个回答
0
投票

从 Spring 3.0 开始,您所描述的场景可以通过

ConverterFactory
接口的实现来覆盖。当您需要集中整个类层次结构的转换逻辑(例如
ConverterFactory
)并根据需要转换到的子类型返回不同的
Enum
(例如
Converter
TimeUnit
)时,
DayOfWeek
非常适合,或其他。

ConverterFactory
接口的声明如下,其中:

  • S
    是要转换的类型。例如
    String
  • R
    是要转换为的基本类型。例如,在您的情况下为
    Number
    Enum
  • T
    R
    的子类型,也是要转换为的实际类型。例如,如果
    Integer
    R
    ,则为
    Number
    ;如果
    TimeUnit
    DayOfWeek
    ,则为
    R
    Enum
    等任何枚举。
public interface ConverterFactory<S, R> {
    <T extends R> Converter<S, T> getConverter(Class<T> targetType);
}

您的实现可能如下所示:

final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {

    public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToEnumConverter<>(targetType);
    }

    private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> {

        private final Class<T> enumType;

        public StringToEnumConverter(Class<T> enumType) {
            this.enumType = enumType;
        }

        public T convert(String source) {
            return (T) Enum.valueOf(this.enumType, source.trim());
        }
    }
}

可能的用法如下:

public class Main {
    public static void main(String[] args) {
        StringToEnumConverterFactory converterFactory = new StringToEnumConverterFactory();
        TimeUnit timeUnit = converterFactory.getConverter(TimeUnit.class).convert("MINUTES");
        DayOfWeek dayOfWeek = converterFactory.getConverter(DayOfWeek.class).convert("MONDAY");
    }
}

这里是 Spring 框架教程的 Using ConverterFactory 段落的链接,以进一步讨论有关转换器的主题。


-2
投票

枚举类型在java架构设计中是最终的,你不应该在项目中创建扩展此类型的类。

参考:

链接1

链接2

© www.soinside.com 2019 - 2024. All rights reserved.