通用参数的Singleton Bean实例

时间:2014-09-03 15:37:34

标签: java spring generics

我希望基于单个@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> {
    ...
}

其中ClazzAIClazzAOClazzBIClazzBO是基本的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的两个实现:MapperAMapperB,即使我指定了我想要的实现参数。< / p>

任何想法如何制作它而不需要在@Configuration class中实例化所有这些bean?

2 个答案:

答案 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

的回答