通过通用参数的Singleton Bean实例

Bas*_*sta 3 java generics spring

我想有一个基于单个@Component通用类的通用参数的单例bean实例。

(我正在使用Spring4。)

我的代码:

我有一个interface这样的:

public interface Mapper<I, O> {
    ...
}
Run Code Online (Sandbox Code Playgroud)

以及Spring @Component的多个实现(子集)。像这样的东西:

@Component
public class MapperA implements Mapper<ClazzAI, ClazzAO> {
    ...
}
Run Code Online (Sandbox Code Playgroud)

@Component
public class MapperB implements Mapper<ClazzBI, ClazzBO> {
    ...
}
Run Code Online (Sandbox Code Playgroud)

其中ClazzAIClazzAOClazzBIClazzBO是基本的Java类。

我有另一个Spring @Component(singleton),它具有a 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;
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

我想这样使用它:

@Inject
private TransformerImpl<ClazzAI, ClazzAO, MapperA> transformerA;

@Inject
private TransformerImpl<ClazzBI, ClazzBO, MapperB> transformerB;
Run Code Online (Sandbox Code Playgroud)

问题 :

但是Spring无法实例化这2个对象,因为它找到了2种实现MapperMapperAMapperB即使我将我想要的实现指定为通用参数。

知道如何在不实例化a中所有这些bean的情况下实现它@Configuration class吗?

Sot*_*lis 5

您要单身,但需要两个注射点

@Inject
private TransformerImpl<ClazzAI, ClazzAO, MapperA> transformerA;

@Inject
private TransformerImpl<ClazzBI, ClazzBO, MapperB> transformerB;
Run Code Online (Sandbox Code Playgroud)

用于不同构造的对象。那没有多大意义。

您现在意识到需要两个bean。如果您不能(不想)在@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

处理注射目标时

@Inject
private TransformerImpl<ClazzAI, ClazzAO, MapperA> transformerA;
Run Code Online (Sandbox Code Playgroud)

Spring将找到MapperATransformerImpl类型的TransformerImpl<ClazzAI, ClazzAO, MapperA>并将其注入。