Java 是否可以销毁CDI范围?

Java 是否可以销毁CDI范围?,java,jakarta-ee,cdi,jboss-weld,Java,Jakarta Ee,Cdi,Jboss Weld,我正在开发一个JavaEE应用程序,主要是带有JSF管理控制台的JAX-RS,它使用CDI/Weld对对象进行依赖注入。撇开小的调试问题不谈,CDI在这个项目中工作得非常出色 现在,我需要对CDI注入的对象生命周期进行一些非常粗粒度的控制。我需要能够: 从应用程序上下文中删除注入的对象,或 销毁/删除/清除/重置/删除整个应用程序上下文,或 在其中,我可以提供执行上述两个任务之一的方法 我完全意识到,这与一般的CDI和依赖注入的粒度是一致的(如果不是相反的话)。我只是想知道 这有可能吗 如

我正在开发一个JavaEE应用程序,主要是带有JSF管理控制台的JAX-RS,它使用CDI/Weld对对象进行依赖注入。撇开小的调试问题不谈,CDI在这个项目中工作得非常出色

现在,我需要对CDI注入的对象生命周期进行一些非常粗粒度的控制。我需要能够:

  • 从应用程序上下文中删除注入的对象,或
  • 销毁/删除/清除/重置/删除整个应用程序上下文,或
  • 在其中,我可以提供执行上述两个任务之一的方法
我完全意识到,这与一般的CDI和依赖注入的粒度是一致的(如果不是相反的话)。我只是想知道

  • 这有可能吗
  • 如果是,完成工作的最简单/最简单/最快/最简单的方法是什么

开箱即用,只有对话范围可以让您完全控制其生命周期。但如果对话不符合您的需要,您可以创建自己的范围。
创建范围是一项艰巨的工作,但您可以转到weld代码,看看对话是如何实现的。

weld参考文档

记住,一旦一粒豆子被捆住了 从某种意义上说,它仍然是这样 上下文,直到上下文 摧毁。没有办法手动执行 从上下文中删除bean。如果你 我不想让豆子坐在椅子上 无限期会议,考虑使用 另一个使用寿命较短的范围, 例如请求或对话 范围

自定义范围示例

如果确实不希望采用自定义作用域类型的路径。。您可以通过使用方法使用不可移植的方法,并在焊接中强制转换此上下文,以访问beanstore或上下文的cleanUp()方法


检查此线程,了解如何为您的环境获取实例。

一个可能适合您需要的自定义作用域可能在您需要稍微调整一下实现时可用。

在CDI 1.1中,有一个
javax.enterprise.context.spi.AlterableContext
接口,允许您单独销毁一个bean实例。所有正常作用域(请求、会话、会话)都是可变的

AlterableContext ctxConversation = (AlterableContext) beanManager.getContext(ConversationScoped.class);
for (Bean<?> bean : beanManager.getBeans(Object.class)) {
    Object instance = ctxConversation.get(bean);
    if (instance != null) {
        ctxConversation.destroy(instance);
    }
}
或通过CDI静态方法:

CDI.current().getBeanManager();
,但要注意某些焊接版本中静态方法的问题:

  • )

只是好奇:如果这些对象只是全局对象,即一些静态字段,该怎么办。不涉及DI。在您的特定应用程序中,您能否证明DI对您的应用程序范围对象来说确实很有价值?这对这个应用程序来说是不可能的。我使用DI不仅仅是因为它很有光泽。我认为这根本不违背DI的本质——毕竟,创建CDI规范是为了精确地解决范围生命周期的问题,并明确允许创建新的范围(当然,在上下文中重新创建特定的bean不是CDI方式)我确实已经尝试使用对话范围了——不幸的是,我的简短尝试没有取得成果。看起来自定义作用域是唯一的解决方案,尽管我真的不想走这条路…@Matt Ball抱歉没有看到你真的不想进入自定义作用域类型,所以我编辑了答案,添加了另一个可能的解决方案,我可以看到。谢谢你提供的信息!当我有机会的时候,我一定会尝试这个(不可移植的)方法。这可能会做得很好。。。我想你说的是
DestroyableContext
?是的。至少非常相似。您还可以查看MyFaces CODI的以JSF为中心的作用域,这些作用域也是细粒度的,但是如果您需要一些独立于JSF和/或易于用作自定义作用域模板的内容,那么这个可能适合。
CDI.current().getBeanManager();