jakarta-ee - 为什么使用 CDI 进行自注入不会导致无限循环?
问题描述
为什么这个建筑有效?
@Stateless
public class SomeClass {
@Inject
private SomeClass self;
//...
}
为什么没有对象引用注入的无限递归?容器什么时候意识到该停止了?
解决方案
在这种特殊情况下,您是自注入无状态 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 的目的,以保护您免受无限循环。
推荐阅读
- asp.net-mvc - 使用 @Html.CheckBoxFor 禁用多项选择,同时允许框之间有空格 - ASP.Net (Core) MVC
- android - 如何通过 Uri 链接打开 GooglePhoto 的视频/图像?
- javascript - Bootstrap 中的自适应徽标
- android - Flutter Provider (ChangeNotifierProxyProvider) 失败,因为 hasListeners 为 true
- python - 如何在 Tensorflow 2.0 中将占位符从 Tensorflow 1.0 转换为 tf.keras.input
- r - 从动态字符串向量中提取某些单词
- mysql - 在sql查询中添加日期,vb.net
- java - 如何在 Mockito 中对 if/else 语句进行单元测试
- chai - 与属性深度相等的柴抛
- c++ - Arduino - MagStripe card.available 暂停,没有其他代码可以运行