CDI注入什么时候发生?

When does CDI injection happen?

我正在使用 Wildfly 服务器并想知道注入实际发生的时间。是在需要的时候还是有一些机制可以更早地解决依赖关系?

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

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

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

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

事实上,bean 的创建通常是延迟完成的,尤其是当代理在起作用时(例如任何普通范围的 bean)。这是 Weld-specific,其他 CDI 实现不需要遵守该规范,因为规范本身不 demand/forbid 它。

实际上这意味着当您 @Inject Foo foo; 您得到的实际上是一个代理对象。无状态 'shell' 知道如何在需要时 获取所谓的上下文实例 。上下文实例是在您第一次尝试使用该 bean 时按需延迟创建的,通常是在您第一次尝试对其调用方法时。

由于 CDI 的静态特性,在部署时,您的 bean 的所有依赖项都是已知的并且可以被验证,因此您在问题中的链可以被验证并且您将知道是否所有这些 beans available/unsatisfied/ambiguous.

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