首页 > 解决方案 > 为什么使用 CDI 进行自注入不会导致无限循环?

问题描述

为什么这个建筑有效?

@Stateless
public class SomeClass {

    @Inject
    private SomeClass self;

    //...
}

为什么没有对象引用注入的无限递归?容器什么时候意识到该停止了?

标签: jakarta-eecdi

解决方案


在这种特殊情况下,您是自注入无状态 EJB。在 Wildfly 的情况下,@Stateless与任何 CDI 范围都没有关联,因此您的 bean 以@Dependent(关于它是否正确的讨论可以在这里找到https://issues.redhat.com/browse/CDI-414)。因此,在 Wildfly 的情况下,它以错误“WELD-001443:伪作用域 bean 具有循环依赖关系”结尾。

当 bean 之一(在您的情况下为同一个 bean)具有正常范围时,CDI 当前支持循环依赖(在您的情况下为自注入):@RequestScoped, @SessionScoped, @ApplicationScoped, @ConversationScoped.

因此@Dependent,伪范围将以 WELD-001443 结束,但其他范围有效,因为框架使用客户端代理(如果您记录@Inject变量,您可以看到 toString() 将打印有关代理对象的信息)。在这个代理 CDI 框架上调用方法之后会进行上下文查找,这就是为什么在这个 bean 初始化期间没有发生无限循环的原因。

对于@Dependent,不使用代理,并创建直接引用。这是 WELD-001443 的目的,以保护您免受无限循环。


推荐阅读