如何在 spring 属性文件中使用嵌套的 java.reflect.Type
How to use a nested java.reflect.Type in a spring properties file
最近遇到一个案例,我想要预先但可配置的类型(长话短说)。通常我这样做
Type t = new TypeToken<ArrayList<Integer>>() {}.getType();
我想将右侧放入我的 spring 属性文件中,然后发出与此类似的调用:
Type t = env.getProperty("type-property");
或者使用@ConfigurationProperties。
我通常使用@ConfigurationProperties,但我所在的存储库没有它。如果第一种方法根本不可能,我可以考虑引入依赖项,但阻力最小的路径更可取。
我尝试了以下带有尖括号、圆括号和方括号的 属性 定义的一些变体 --- none 成功了。
type-property=java.util.ArrayList<java.lang.Integer>
对于您被迫用于解决此问题的各种搜索词,我很难得到任何有用的信息。我发现了这个相关的问题,但没有运气将它翻译成非 xml 配置(我也不能在这个项目中做 xml 风格)。 link: Create a Guava TypeToken in Spring xml config?
编辑:
使用@LppEdd 提供的答案,我对 de/serialization:
使用了以下调用
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);
回答您的 "translating to Java" 点:
@Bean
@Qualifier("IntegerArrayList")
public Type integerArrayList() {
return new TypeToken<ArrayList<Integer>>() {}.getType();
}
用法:
@Autowired
@Qualifier("IntegerArrayList")
private Type type;
或者...
我会帮你开始的。
"better" 方法是将 @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
以外的类型。
您是否考虑过使用 Spring SPEL?它几乎可以为您完成解决方案,除非由于对泛型的支持不佳,您需要为 TypeToken
.
的每个子 class 创建单独的 class
例如具体 class 的 :
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;
最近遇到一个案例,我想要预先但可配置的类型(长话短说)。通常我这样做
Type t = new TypeToken<ArrayList<Integer>>() {}.getType();
我想将右侧放入我的 spring 属性文件中,然后发出与此类似的调用:
Type t = env.getProperty("type-property");
或者使用@ConfigurationProperties。
我通常使用@ConfigurationProperties,但我所在的存储库没有它。如果第一种方法根本不可能,我可以考虑引入依赖项,但阻力最小的路径更可取。
我尝试了以下带有尖括号、圆括号和方括号的 属性 定义的一些变体 --- none 成功了。
type-property=java.util.ArrayList<java.lang.Integer>
对于您被迫用于解决此问题的各种搜索词,我很难得到任何有用的信息。我发现了这个相关的问题,但没有运气将它翻译成非 xml 配置(我也不能在这个项目中做 xml 风格)。 link: Create a Guava TypeToken in Spring xml config?
编辑: 使用@LppEdd 提供的答案,我对 de/serialization:
使用了以下调用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);
回答您的 "translating to Java" 点:
@Bean
@Qualifier("IntegerArrayList")
public Type integerArrayList() {
return new TypeToken<ArrayList<Integer>>() {}.getType();
}
用法:
@Autowired
@Qualifier("IntegerArrayList")
private Type type;
或者...
我会帮你开始的。
"better" 方法是将 @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
以外的类型。
您是否考虑过使用 Spring SPEL?它几乎可以为您完成解决方案,除非由于对泛型的支持不佳,您需要为 TypeToken
.
例如具体 class 的 :
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;