在 Spring 中注入多个冲突依赖项
Injection of Multiple Conflicting Dependencies in Spring
我有一个 Spring bean class 请求注入依赖项。但是,在我的 class 中,我手动将不同的依赖项连接到同一个私有 class 变量。在这种情况下会发生什么?哪种注射先行?
详情:
我创建了一个名为 BadmintonCoach 的 Spring bean class。
它依赖于一个 IfortuneService 助手。 IfortuneService 是具有两种不同实现的接口。两个实现是:
- FortuneService_RESTful
- 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 的回答中可以看到这种危险的例证
我有一个 Spring bean class 请求注入依赖项。但是,在我的 class 中,我手动将不同的依赖项连接到同一个私有 class 变量。在这种情况下会发生什么?哪种注射先行?
详情:
我创建了一个名为 BadmintonCoach 的 Spring bean class。
它依赖于一个 IfortuneService 助手。 IfortuneService 是具有两种不同实现的接口。两个实现是:
- FortuneService_RESTful
- 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()
orClass.getMethods()
. Neither of these methods return the methods in any particular order.
我仍然对 Spring(即:Class.getDeclaredMethods()
或 Class.getMethods()
)执行相同逻辑如何产生这样的随机结果感到困惑。
了解此限制非常重要!在编写代码时,您可能会发现自己想要使用注入依赖项的服务,而这些依赖项又依赖于其他注入依赖项的服务。从这个实验中可以清楚地看出,这可能是危险的,因此您不应该以这种方式分层布线。也就是说,如果它跨越多个方法,您的连接应该始终是单层的,否则,您的程序可能会出现虚假输出。在