所以,我有一些通用组件,它们使用反射来初始化自己,并且在这样做时,需要在实例化时提供Class<T>
对象。这些组件使用注释来生成有用的元数据和/或将对象转换为更适合手头任务的另一种表示形式。
我将我的问题简化为此示例组件:
@Component
public class Instantiator<T> {
final Class<T> klass;
@Autowired
public Instantiator(Class<T> klass) {
this.klass = klass;
}
public T instantiate() {
try {
return klass.newInstance();
} catch (InstantiationException|IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Spring不知道如何自动注入Class<T>
实例,因此为了每个我想要Class<T>
可用的T
编写了以下样板代码。
@Bean
Class<Instantiatee> instantiateeClass() {
return Instanciatee.class;
}
它不起作用。
自Spring 4版本以来,支持对泛型类型进行自动装配,但在我的情况下,必须推断出T
分配给了Class<T>
。由于默认情况下Spring创建单例bean,因此无法推断出适当的T
,我尝试添加@Scope("prototype")
,但最终出现了ClassCastException
,因为容器不知道如何推断T
。
因此,我从Instantiator中删除了@Component
注释,并为我拥有的每个T
解决了这个问题:
@Bean
Instantiator<Instantiatee> instantiator() {
return new Instantiator<>(Instantiatee.class);
}
你是否了解一种解决办法,以便每次我想要一个依赖于
T
的Instantiator
或另一个泛型组件时都可以推断出它?FYI,我们正在使用spring 4.1.4和boot。
我在这里发布了更完整的示例:https://gist.github.com/anonymous/79e1a7ebe7c25c00a6c2。
Instanciator
bean?请发布完整的NoSuchBeanDefinitionException
堆栈跟踪,我无法重现它(但我也不知道你尝试了什么)。 - Sotirios Delimanolis