是否有可能毁掉 CDI 瞄准镜?

发布于 2024-11-16 19:09:58 字数 724 浏览 3 评论 0 原文

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

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

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

我完全意识到,这即使不是违背的话,也与 CDI 和依赖注入的本质相悖。我只是想知道

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

I'm working on a Java EE application, primarily JAX-RS with a JSF admin console, that uses CDI/Weld for dependency injection with javax.enterprise.context.ApplicationScoped objects. Minor debugging issues aside, CDI has worked beautifully for this project.

Now I need some very coarse-grained control over CDI-injected object lifecycles. I need the ability to:

  • Remove an injected object from the application context, or
  • Destroy/delete/clear/reset/remove the entire application context, or
  • Define my own @ScopeType and implementing Context in which I could provide methods to perform one of the two above tasks.

I'm fully aware that this is across, if not against, the grain of CDI and dependency injection in general. I just want to know

  • Is this remotely possible?
  • If yes, what is the easiest/simplest/quickest/foolproofiest way to get the job done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时光瘦了 2024-11-23 19:09:58

焊接参考文档 第 2.1.2 节

请记住,一旦 Bean 被绑定
就上下文而言,它仍然存在于
上下文直到上下文是
被毁了。没有办法手动
从上下文中删除一个bean。如果你
不想让豆子留在里面
无限期会话,考虑使用
另一种寿命较短的瞄准镜,
例如请求或对话
范围。

自定义作用域示例 移植 veiwscoped jsf 注释到 cdi

如果您确实不想采用自定义范围类型的路径..您可以使用不可移植方法通过使用BeanManager .getContext 方法并将此上下文投射到焊接 AbstractSharedContext 可以访问 beanstore 或上下文的 cleanUp() 方法。

查看此主题,了解如何获取适合您环境的 BeanManager 实例

Weld Reference Documentation Section 2.1.2

Keep in mind that once a bean is bound
to a context, it remains in that
context until the context is
destroyed. There is no way to manually
remove a bean from a context. If you
don't want the bean to sit in the
session indefinitely, consider using
another scope with a shorted lifespan,
such as the request or conversation
scope.

Custom scope example Porting the veiwscoped jsf annonation to cdi

If you really don't want to take the path of the Custom scope type.. You can use a non-portable method by using BeanManager.getContext method and cast this context in a weld AbstractSharedContext to have access to the beanstore or the cleanUp() method of the context.

Check this thread on how to get a BeanManager instance for your environment

琉璃繁缕 2024-11-23 19:09:58

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

Out of the box there is only the Conversation scope that gives you total control on its lifecycle. But you can create your own scope if conversation doesn't suit your needs.
Creating a scope is a tough job, but you can go to weld code and look how conversation was implemented.

安静被遗忘 2024-11-23 19:09:58

在 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 实例。 获取它

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

您可以通过 JNDI 查找:或通过 CDI 静态方法:

CDI.current().getBeanManager();

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

In CDI 1.1 there is a javax.enterprise.context.spi.AlterableContext interface, which allows you to individually destroy a bean instance. All normal scopes (request, conversation, session) are alterable.

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

The beanManager here is a javax.enterprise.inject.spi.BeanManager instance. You can get it via JNDI lookup:

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

or via CDI static method:

CDI.current().getBeanManager();

, but be aware of the issues with the static method in some Weld versions:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文