是否有可能破坏CDI范围?

我正在开发一个Java EE应用程序,主要是带有JSF管理控制台的JAX-RS,它使用CDI / Weld通过javax.enterprise.context.ApplicationScoped对象注入依赖javax.enterprise.context.ApplicationScoped 。 除了一些小的调试问题,CDI已经为这个项目做了很好的工作。

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

  • 从应用程序上下文中删除注入的对象,或
  • 销毁/删除/清除/重置/删除整个应用程序上下文,或
  • 定义我自己的@ScopeType并实现Context ,我可以在其中提供执行上述两个任务之一的方法。

我完全清楚,如果不是反对CDI和dependency injection的一般情况,这是相互影响的。 我只是想知道

  • 这远程可能吗?
  • 如果是,那么完成工作最简单/最简单/最快/最愚蠢的方法是什么?

焊接参考文献第2.1.2节

请记住,一旦bean绑定到上下文,它就会保留在该上下文中,直到上下文被销毁。 无法从上下文中手动删除bean。 如果您不希望bean无限期地坐在会话中,请考虑使用具有缩短生命周期的另一个范围,例如请求或会话范围。

自定义范围示例将veiwscoped jsf annonation移植到cdi

如果您真的不想采用自定义范围类型的路径。您可以使用BeanManager.getContext方法使用非可移植方法,并在焊接AbstractSharedContext中转换此上下文以访问beanstore或cleanUp( )上下文的方法。

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

可从https://github.com/openknowledge/openknowledge-cdi-extensions/tree/master/openknowledge-cdi-scope/src/main/java/de/openknowledge/cdi/scope获取可能符合您需求的自定义范围。也许你必须稍微调整一下实现。

开箱即用只有Conversation范围可以让您完全控制其生命周期。 但如果对话不符合您的需求,您可以创建自己的范围。 创建一个范围是一项艰巨的任务,但您可以去焊接代码并查看如何实现对话。

在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); } } 

这里的beanManager是一个javax.enterprise.inject.spi.BeanManager实例。 您可以通过JNDI查找获取它:

 InitialContext.doLookup("java:comp/BeanManager"); 

或通过CDI静态方法:

 CDI.current().getBeanManager(); 

,但请注意一些Weld版本中静态方法的问题:

  • javax.enterprise.inject.spi.CDI实现不支持多个部署 ;
  • CDI.current()。getBeanManager()从不同的部署返回beanmanager 。