如何在Spring属性文件中使用嵌套的java.reflect.Type

时间:2019-02-11 21:29:40

标签: java spring spring-properties

最近遇到一种情况,我想要预先但可配置的类型(长话短说)。通常我会这样做

Type t = new TypeToken<ArrayList<Integer>>() {}.getType();

我想将该右手放在我的spring属性文件中,并发出类似于以下的调用:

Type t = env.getProperty("type-property");

或使用@ConfigurationProperties。

我通常使用@ConfigurationProperties,但是我所在的存储库没有可用的。如果根本不可能采用第一种方法,那么我可以考虑引入依赖关系,但最好选择阻力最小的路径。

我尝试使用尖括号,括号和方括号对以下属性定义进行一些变体,但均未解决。

type-property=java.util.ArrayList<java.lang.Integer>

对于您被迫使用此问题的各种搜索字词,我很难获得任何有用的信息。我找到了这个相关的问题,但是没有运气将其转换为非xml配置(我也不能在该项目中执行xml样式)。链接:Create a Guava TypeToken in Spring xml config?

编辑: 使用@LppEdd提供的答案,我将以下调用用于反序列化:

Type sampleType = new TypeToken<HashSet<ArrayList<Integer>>>() {}.getType();
// serialize via java.lang.reflect.Type.getTypeName()
String serializedType = sampleType.getTypeName();
// above string value is "java.util.HashSet<java.util.ArrayList<java.lang.Integer>>"
// deserialize via org.eclipse.jetty.util.TypeUtil.fromName(String name)
Type sampleTypeAgain = TypeUtil.fromName(serializedType);

2 个答案:

答案 0 :(得分:0)

要回答您的“翻译成Java”要点:

@Bean
@Qualifier("IntegerArrayList")
public Type integerArrayList() {
   return new TypeToken<ArrayList<Integer>>() {}.getType();
}

用法:

@Autowired
@Qualifier("IntegerArrayList")
private Type type;

或者...

从这里开始。
“更好”的方法是将@ConfigurationProperties与自定义PropertySource实现一起使用。所有Type子类都应该可序列化,因此您可以存储序列化的数据并即时进行反序列化。

显然,这些字段的名称将与Type(s)映射键相对应。

class TypePropertySource extends PropertySource<TypeSource> {
    private final TypeSource source;

    TypePropertySource(final TypeSource source) {
        super("a-name", source);
        this.source = source;
    }

    @Override
    public Object getProperty(final String name) {
        try {
            return (Type) source.getAndDeserialize(name);
        } catch (final Exception e) {
            // Recover or do nothing.
        }

        return null;
    }
}

编辑:我真的不知道Spring中的属性值是否支持String以外的类型。

答案 1 :(得分:0)

您是否考虑过使用Spring SPEL?除了对泛型的不良支持之外,它几乎可以为您解决问题,您需要为TypeToken的每个子类创建单独的类。

例如,具体类为:

import java.util.ArrayList;
import com.google.common.reflect.TypeToken;

public class MyType extends TypeToken< ArrayList<Integer> >{

}

您可以拥有这样的财产:

type-property: new com.comcast.viser.ipPreference.web.MyType().getType()

并像这样注入它:

@Value("#{${type-property}}")
private java.lang.reflect.Type type;