【问题标题】:When does CDI injection happen?CDI 注入何时发生?
【发布时间】:2019-10-19 19:09:42
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: jboss wildfly cdi


    【解决方案1】:

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

    事实上,bean 创建通常是延迟完成的,尤其是在代理运行时(例如任何普通作用域的 bean)。这是 Weld 特有的,其他 CDI 实现不需要遵守这一点,因为规范本身并不要求/禁止它。

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

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

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

    【讨论】:

    • 非常感谢。那么,就是 CDI.current().select(MyStatelessBean.class).get();和'@Inject Instance bean;同样的',第二个只是进行初始验证?那么池化呢?如果,例如我有'@Stateless' bean,我想将它作为一些长链 bean 的一部分注入(如上所述)。通过代理调用 bean 的代码是否必须等到容器从池中获取空闲 bean?我在这里想到了 ejbs 的并发性。
    • 是的,CDI.current() 基本上是获取当前 bean 存档的Instance<T> 的一种方式。至于pooling,CDI本身不知道pooling;那是 EJB 特性,事实上,它甚至不需要存在(服务器可以以不同的方式解决它)。 EJB 和 CDI 之间有一个集成层,它允许您像使用 CDI 一样使用 EJB bean;在 WFLY 中有一种真实 EJB 实例的外观,Weld 使用它来实现这一点。因此,真正的问题更多是关于 WFLY 如何处理池化,或者它是否总是为您提供新实例。我不知道。
    猜你喜欢
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 2018-03-04
    相关资源
    最近更新 更多