弹簧无法自动布线,有多个“”类型的豆子

2022-09-01 17:18:28

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

服务类在基接口上有一个依赖项,代码是这样的:

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

服务类具有依赖关系,基接口将决定通过某些业务逻辑自动连接哪个实现。代码是这样的:


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

    private AutowiredClazz(BaseInterface baseInterface){
        this.baseInterface = baseInterface;
    }
}

IDEA抛出一个异常:无法自动连线。有不止一种豆类类型。BaseInterface

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

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

我试图阅读Spring文档,它提供了一个基于构造函数的依赖注入,但我仍然对这个问题感到困惑。

任何人都可以帮助我吗?


答案 1

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

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

答案 2

这不能仅通过使用弹簧框架来解决。你提到基于一些逻辑,你需要一个BaseInterface的实例。此用例可以使用工厂模式解决。创建一个豆子,它实际上是BaseInterface的工厂

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

推荐