Singleton Bean实例通过泛型参数 [英] Singleton Bean instance by generic parameter

查看:191
本文介绍了Singleton Bean实例通过泛型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过基于单个 @Component 泛型类的泛型参数来创建单例bean实例。



< (我正在使用Spring 4)。



我的代码

  public interface Mapper< I, O> {
...
}

它的多重实现是Spring @Component s(单身人士)。类似这样:

  @Component 
public class MapperA实现Mapper< ClazzAI,ClazzAO> {
...
}

  @Component 
public class MapperB实现Mapper< ClazzBI,ClazzBO> {
...
}

其中 ClazzAI , ClazzAO ClazzBI ClazzBO @Component (singleton),它有一个<$ c
$ b $ pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ code> @Component
public class TransformerImpl< I,O,M扩展Mapper< I,O>> {

/ **映射器* /
保护的最终M映射器;

@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 ,即使我指定了我希望作为通用参数的实现。



任何想法如何无需在 @Configuration class

$ b $中实例化所有这些bean b

解决方案

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

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

@Inject
private TransformerImpl< ClazzBI,ClazzBO,MapperB> transformerB;

用于不同构造的对象。这没有什么意义。

你现在意识到你需要两个豆子。如果你不能(不想)在 @Configuration 类中使用 @Bean 工厂方法,你需要声明(并扫描)两个单独的 @Component 类。 (我把你的父构造器公开在这里)。

$ b $ p
class MapperATransformerImpl extends TransformerImpl< ClazzAI,ClazzAO,MapperA> ; {
@Inject
public MapperATransformerImpl(MapperA mapper){
super(mapper);
}
}

@Component
class MapperBTransformerImpl扩展了TransformerImpl< ClazzBI,ClazzBO,MapperB> {
@Inject
public MapperBTransformerImpl(MapperB mapper){
super(mapper);
}
}

处理注入目标时

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

Spring会找到 MapperATransformerImpl ,它是类型为 TransformerImpl 并注入。


I would like to have a singleton bean instance by generic parameter based on a single @Component generic class.

(I am using Spring 4.)

My code :

I have an interface like this :

public interface Mapper<I, O> {
    ...
}

And multiple implementation of it which are Spring @Components (singletons). Something like this :

@Component
public class MapperA implements Mapper<ClazzAI, ClazzAO> {
    ...
}

and

@Component
public class MapperB implements Mapper<ClazzBI, ClazzBO> {
    ...
}

where ClazzAI, ClazzAO, ClazzBI and ClazzBO are basic Java classes.

I have another Spring @Component (singleton) which have a Mapper class as a generic parameter :

@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;
    }

    ...
}

and I would like to use it like this :

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

@Inject
private TransformerImpl<ClazzBI, ClazzBO, MapperB> transformerB;


The problem :

But Spring is not able to instantiate those 2 objects because it founds 2 implementations of Mapper : MapperA and MapperB even if I specify which implementation I want as a generic parameter.

Any idea how to make it without the need of instantiate all of those beans in a @Configuration class ?

解决方案

You're asking for a singleton but requiring two injection points

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

@Inject
private TransformerImpl<ClazzBI, ClazzBO, MapperB> transformerB;

for differently constructed objects. That doesn't make much sense.

You now realize you need two beans. If you can't (don't want to) do it in a @Configuration class with @Bean factory methods, you'll need to declare (and scan) two separate @Component classes. (I made your parent constructor public here.)

@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);
    }
}

When processing the injection target

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

Spring will find the MapperATransformerImpl, which is of type TransformerImpl<ClazzAI, ClazzAO, MapperA> and inject that.

这篇关于Singleton Bean实例通过泛型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆