Spring无法自动assembly,有多个“类型的bean

这是我的问题:我有一个基本接口和两个实现类。

Service类对基接口有依赖关系,代码如下:

@Component public interface BaseInterface {} 

 @Component public class ClazzImplA implements BaseInterface{} 

 @Component public class ClazzImplB implements BaseInterface{} 

配置是这样的:

 @Configuration public class SpringConfig { @Bean public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean public BaseInterface clazzImplB(){ return new ClazzImplB(); } } 

服务类依赖于基接口将决定通过某些业务逻辑自动assembly哪个实现。代码如下:


 @Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired private BaseInterface baseInterface; private AutowiredClazz(BaseInterface baseInterface){ this.baseInterface = baseInterface; } } 

并且IDEA抛出exception:无法自动assembly。有多个BaseInterface类型的bean。

虽然可以通过@ Qualifier来解决,但在这种情况下我无法选择依赖类。

 @Autowired @Qualifier("clazzImplA") private BaseInterface baseInterface; 

我试图阅读spring文档,它提供了一个Constructor-based dependency injection但我仍然对这个问题感到困惑。

谁能帮我 ?

Spring在您在配置类中声明的两个bean之间混淆,因此您可以使用@Qualifier注释和@Autowired通过指定要连接的确切bean来消除混淆,在配置类上应用这些修改

 @Configuration public class SpringConfig { @Bean(name="clazzImplA") public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean(name="clazzImplB") public BaseInterface clazzImplB(){ return new ClazzImplB(); } } 

然后在@autowired注释

 @Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired @Qualifier("the name of the desired bean") private BaseInterface baseInterface; private AutowiredClazz(BaseInterface baseInterface){ this.baseInterface = baseInterface; } } 

仅使用spring框架无法解决这个问题。 您提到基于某些逻辑,您需要一个BaseInterface实例。 可以使用Factory Pattern解决此用例。 创建一个实际上是BaseInterface工厂的Bean

 @Component public class BaseInterfaceFactory{ @Autowired @Qualifier("clazzImplA") private BaseInterface baseInterfaceA; @Autowired @Qualifier("clazzImplb") private BaseInterface baseInterfaceB; public BaseInterface getInstance(parameters which will decides what type of instance you want){ // your logic to choose Instance A or Instance B return baseInterfaceA or baseInterfaceB } } 

配置(从另一个评论中无耻地复制)

 @Configuration public class SpringConfig { @Bean(name="clazzImplA") public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean(name="clazzImplB") public BaseInterface clazzImplB(){ return new ClazzImplB(); } } 

服务类

 @Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired private BaseInterfaceFactory factory; public void someMethod(){ BaseInterface a = factory.getInstance(some parameters); // do whatever with instance a } } 

如果您使用@ @Autowired ,Spring会搜索与您要自动assembly的字段类型匹配的bean。 在您的情况下,有多个BaseInterface类型的BaseInterface 。 这意味着Spring无法明确地选择匹配的bean。

在这种情况下,您没有其他选择来显式声明Spring应该使用的bean或解决歧义。

这里正确地回答说,在这种情况下,接口由多个类实现,我们必须使用@Component(name=$beanName)命名每个bean。

我想补充一点,在这种情况下,Spring甚至可以在地图中自动assembly这样的bean:

 @Autowired Map interfaceMap; //this will generate beans and index them with beanName as key of map