【问题标题】:How to choose what implementation get's injected in to an autowired constructor如何选择将什么实现注入到自动装配的构造函数中
【发布时间】:2017-02-19 12:27:36
【问题描述】:

假设我有一个界面

interface IPerson {...}

我有这个接口的两个实现

@Component
class Programmer implements IPerson {...}

@Component
class LionTamer implements IPerson {...}

假设我有一个使用 Autowire 注入的类

@Component
class SomethingThatDoesStuff { 

    @Autowired
    public SomethingThatDoesStuff (IPerson someone) {
        ...
    }

}

Spring 如何知道要注入什么实现?有没有办法告诉spring注入什么实现?这可以通过注释来完成,还是我必须定义某种工厂?如果有怎么办?

【问题讨论】:

  • @qualifier 会做
  • 如果你运行上面的代码,理想情况下你会得到一个 Spring 初始化错误,因为它是接口的两个实现。正如上面评论中提到的,您可以为两个实现添加限定符名称,并且在@Autowire 中您可以提及限定符名称。
  • 这是重复的
  • @RolsonQuadras 你能用代码示例发布答案吗?
  • 如果你符合条件并在SomethingThatDoesStuff 中选择一个,那不就和完全不使用构造函数di 一样吗?我的意思是我猜你仍然可以在测试中使用它,但是对于代码,如果你需要更改哪一个,无论哪种方式你都需要更新类中的依赖项

标签: java spring spring-boot inversion-of-control autowired


【解决方案1】:

正如@passion 提到的,你应该使用bean命名(standard Spring IoC feature):

@Component("programmer")
class Programmer implements IPerson {...}

@Component("lionTamer")
class LionTamer implements IPerson {...}

@Component
class SomethingThatDoesStuff { 

    @Autowired
    public SomethingThatDoesStuff (@Qualifier("programmer") IPerson someone) {
        ...
    }

}

【讨论】:

  • 在 SomethingThatDoesStuff 构造函数的签名中只要求 Programmer 类型不是更优雅吗?
  • 也许可以,但在这种情况下,您可能希望利用 IPerson 提供的多态性。为什么要使用该接口?
  • 如果你可以传递一个类类型而不仅仅是一个字符串会很酷
猜你喜欢
  • 2022-10-24
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
相关资源
最近更新 更多