在 Spring 中注入多个冲突依赖项

Injection of Multiple Conflicting Dependencies in Spring

我有一个 Spring bean class 请求注入依赖项。但是,在我的 class 中,我手动将不同的依赖项连接到同一个私有 class 变量。在这种情况下会发生什么?哪种注射先行?

详情:
我创建了一个名为 BadmintonCoach 的 Spring bean class。

它依赖于一个 IfortuneService 助手。 IfortuneService 是具有两种不同实现的接口。两个实现是:

  1. FortuneService_RESTful
  2. FortuneService_Random

在我的羽毛球教练 class 中,我创建了一个私有变量来接收来自 Spring 的注入:

private IFortuneService theFortuneService

也就是说,我手动将注入的依赖连接到这个私有成员,theFortuneService

我正在使用注入方法注入这些 iFortuneService 依赖项。

但这就是问题所在:我有两种方法,这两种方法都要求从 Spring 类型的 iFortuneService 进行注入。一种方法请求一种实现 (FortuneService_RESTful),另一种方法请求另一种实现的 bean (FortuneService_Random)。

这两种方法都将 this.theFortuneService 设置为其各自请求的助手。所以我在我的 BadmintonCoach class 中拥有的是:

private IFortuneService theFortuneService

@Autowired
@Qualifier("fortuneService_Random")
public void randomMethod_ONE(IFortuneService theFortuneService) {
    System.out.println("Code inside randomMethod_ONE!");
    this.theFortuneService = theFortuneService;
}


@Autowired
@Qualifier("fortuneService_RESTful")
public void randomMethod_TWO(IFortuneService theFortuneService) {
    System.out.println("Code inside randomMethod_TWO!");
    this.theFortuneService = theFortuneService;
}

那么我的问题是:
两种接线方式中哪一种更胜一筹?为什么? Spring 如何决定其注入的顺序?什么决定了注射的顺序?是随机的吗?它是按方法名称的字母顺序注入的吗?构造函数、setter、字段和方法注入之间是否有注入顺序?

当我 运行 我的程序时,我看到了什么?我看到 fortuneService_RESTful 的注入成功了,但我不清楚这是偶然的还是 Spring 逻辑中的设计。

这是另一个想法:
如果上面的两个方法不是请求 IFortuneService 接口的不同实现,而是请求同一个 bean 但那个 bean 是 prototyped 会怎么样?显然,每个请求都会创建一个新的化身,并且 只有一个助手 class 分配给我的 BadmintonCoach class。但哪个化身会胜出?

如果能让我的问题更清楚,我可以提供我的全部代码。

如果您想知道为什么我编写了冲突的代码?尝试了解 Spring 如何在幕后工作是一种简单明了的好奇心。

好的,我花了一天时间才看到这个,但我可以确认这里发生的事情确实是 随机的!

昨天,我只看到 method_ONE 获胜。今天,我看到 method_TWO 获胜。因此,我可以得出结论,Spring 注射顺序 确实是随机的!

Thomas Klager 在上面的评论中提供了一个可以解释这种现象的建议:

One obvious reason [for this] is that using annotation based injections, spring needs to list the methods of a class using Class.getDeclaredMethods() or Class.getMethods(). Neither of these methods return the methods in any particular order.

我仍然对 Spring(即:Class.getDeclaredMethods()Class.getMethods())执行相同逻辑如何产生这样的随机结果感到困惑。

了解此限制非常重要!在编写代码时,您可能会发现自己想要使用注入依赖项的服务,而这些依赖项又依赖于其他注入依赖项的服务。从这个实验中可以清楚地看出,这可能是危险的,因此您不应该以这种方式分层布线。也就是说,如果它跨越多个方法,您的连接应该始终是单层的,否则,您的程序可能会出现虚假输出。在 .

中 Slim 的回答中可以看到这种危险的例证