CDI注入何时发生?

时间:2019-06-04 09:05:28

标签: jboss wildfly cdi

我正在使用Wildfly服务器,想知道注入何时真正发生。是在需要时还是有某种机制可以更早地进行依赖关系解析?

如果我使用注释@Inject,我知道如果无法注入某些内容(歧义等),我会得到一个错误。这是否意味着在部署时间内完成了注入?如果是这样,与这种情况有什么关系:假设我有BeanOne注入了BeanTwo,而BeanTwo注入了BeanThree。这是否意味着将在部署时分配该bean链?如果我的链数比这个多,并且假设我的bean池限制为几个,比如2,会发生什么?如果没有足够的bean并且其中的一些bean必须等待它们的依赖关系,那么如何在部署期间完成呢?

这种情况是否与以编程方式查找bean不同:CDI.current().select(MyStatelessBean.class).get();

甚至使用实例进行注入:@Inject Instance<MyStatelessBean> bean;

1 个答案:

答案 0 :(得分:2)

您遇到的错误通常来自验证阶段。这是在部署期间完成的,并不意味着将创建实际的bean。

实际上,bean的创建通常是懒惰的,尤其是在代理运行时(例如,任何普通作用域的bean)。这是针对Weld的,并且其他CDI实现不需要遵守该规范,因为该规范本身并不需要/禁止它。

实际上,这意味着当您@Inject Foo foo;时,所获得的实际上是一个代理对象。一个无状态的“外壳”,它知道如何在需要时获取所谓的上下文实例。当您首次尝试使用该bean时(通常是您首次尝试在其上调用方法时),将根据需要延迟创建上下文实例。

由于CDI的静态特性,在部署时,您的bean的所有依赖项都是已知的并且可以验证,因此可以验证问题中的链,并且您将知道所有这些bean是否可用/不满意/模棱两可。

关于动态分辨率,例如Instance<Bar>,这有些不同。 CDI只能验证您拥有的初始声明;在上面的示例中,一个类型为Foo且具有默认限定符的bean。对.select()方法的所有后续调用都是在运行时完成的,因此,您始终需要验证刚刚尝试选择的实例是否可用,因为您可以轻松地选择不是bean或bean类型但无效的类型。限定词。 Instance API为此提供了特殊的方法。