Spring无法自动装配,有多个``类型的bean

gou*_*ner 15 java spring

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

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

@Component
public interface BaseInterface {}
Run Code Online (Sandbox Code Playgroud)
@Component
public class ClazzImplA implements  BaseInterface{}
Run Code Online (Sandbox Code Playgroud)
@Component
public class ClazzImplB implements  BaseInterface{}
Run Code Online (Sandbox Code Playgroud)

配置是这样的:

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

    @Bean
    public BaseInterface clazzImplB(){
        return new ClazzImplB();
    }
}
Run Code Online (Sandbox Code Playgroud)

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


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

    private AutowiredClazz(BaseInterface baseInterface){
        this.baseInterface = baseInterface;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且IDEA抛出异常:无法自动装配.有多个BaseInterface类型的bean .

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

@Autowired
@Qualifier("clazzImplA")
private BaseInterface baseInterface;
Run Code Online (Sandbox Code Playgroud)

我试着阅读弹簧文档并提供了一个,Constructor-based dependency injection但我仍然对这个问题感到困惑.

谁能帮我 ?

Moh*_*bli 18

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在@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;
    }
}
Run Code Online (Sandbox Code Playgroud)


San*_*hav 5

仅使用spring框架无法解决此问题。您提到基于某种逻辑,您需要一个BaseInterface实例。可以使用工厂模式解决该用例。创建一个实际上是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
  }

}
Run Code Online (Sandbox Code Playgroud)

配置(从其他评论中无耻地复制)

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

    @Bean(name="clazzImplB")
    public BaseInterface clazzImplB(){
        return new ClazzImplB();
    }
}
Run Code Online (Sandbox Code Playgroud)

服务等级

@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
    }
}
Run Code Online (Sandbox Code Playgroud)