我希望基于单个@Component
泛型类的泛型参数有一个单例bean实例。
(我正在使用Spring 4.)
我的代码:
我有interface
这样:
public interface Mapper<I, O> {
...
}
它的多个实现是Spring @Component
s(单例)。像这样:
@Component
public class MapperA implements Mapper<ClazzAI, ClazzAO> {
...
}
和
@Component
public class MapperB implements Mapper<ClazzBI, ClazzBO> {
...
}
其中ClazzAI
,ClazzAO
,ClazzBI
和ClazzBO
是基本的Java类。
我有另一个春天@Component
(单身),其Mapper
class
作为通用参数:
@Component
public class TransformerImpl<I, O, M extends Mapper<I, O>> {
/** The Mapper */
protected final M mapper;
@Inject
private TransformerImpl(final M mapper) {
this.mapper= mapper;
}
...
}
我希望像这样使用它:
@Inject
private TransformerImpl<ClazzAI, ClazzAO, MapperA> transformerA;
@Inject
private TransformerImpl<ClazzBI, ClazzBO, MapperB> transformerB;
问题:
但是Spring无法实例化这两个对象,因为它发现了Mapper
的两个实现:MapperA
和MapperB
,即使我指定了我想要的实现参数。< / p>
任何想法如何制作它而不需要在@Configuration
class
中实例化所有这些bean?
答案 0 :(得分:4)
你要求单身但需要两个注射点
@Inject
private TransformerImpl<ClazzAI, ClazzAO, MapperA> transformerA;
@Inject
private TransformerImpl<ClazzBI, ClazzBO, MapperB> transformerB;
用于不同构造的对象。这没有多大意义。
你现在意识到你需要两个豆子。如果您不能(不想)在具有@Configuration
工厂方法的@Bean
类中执行此操作,则需要声明(并扫描)两个单独的@Component
类。 (我在这里公开了你的父构造函数。)
@Component
class MapperATransformerImpl extends TransformerImpl<ClazzAI, ClazzAO, MapperA> {
@Inject
public MapperATransformerImpl(MapperA mapper) {
super(mapper);
}
}
@Component
class MapperBTransformerImpl extends TransformerImpl<ClazzBI, ClazzBO, MapperB> {
@Inject
public MapperBTransformerImpl(MapperB mapper) {
super(mapper);
}
}
处理注射目标时
@Inject
private TransformerImpl<ClazzAI, ClazzAO, MapperA> transformerA;
Spring将找到MapperATransformerImpl
,其类型为TransformerImpl<ClazzAI, ClazzAO, MapperA>
并注入该内容。
答案 1 :(得分:2)
尝试使用Spring 4.请参阅 Using generics as autowiring qualifiers
修改强>
就像@SotiriosDelimanolis在他的回答中解释的那样,Spring 4可以使用类型参数信息作为限定符来选择哪个bean定义与特定注入点匹配,但最后,它只会与具体类型定义的bean定义匹配。在您的情况下,问题是您需要为要注入的每个具体类型定义TransformerImpl bean。
作为明确定义所有bean定义的替代方法,请检查我对Spring autowiring issues on paramaterized class
的回答