CDI.current().select().get() 和 BeanManager.getReference() 在功能上是否相同?

Eri*_* B. 7 java cdi jakarta-ee

在 JEE/CDI 的上下文中,当我需要从方法中静态检索 CDI 托管 bean 时,我发现自己通常使用 CDI 静态函数。例如:

MyBean myBean = CDI.current().select( MyBean.class ).get()
Run Code Online (Sandbox Code Playgroud)

但是,据我所知,实现此目的的另一种等效方法是使用 BeanManager:

BeanManger bm = new InitialContext().lookup( "java:comp/BeanManager" );
Bean<?> bean = bm.resolve(bm.getBeans( MyBean.class ) );
CreationalContext<?> context = bm.createCreationalContext(bean);
MyBean myBean = bm.getReference(bean, cls, context);
Run Code Online (Sandbox Code Playgroud)

那么除了使用该CDI.current()方法编写的代码显着减少之外,使用它还有什么区别?似乎恢复使用BeanManager是一种更复杂(并且可能容易出错?)的方法。从功能的角度来看,使用该CDI.current()方法有什么缺点吗?是否CDI...select()只有一个工作@ApplicationScope豆?或者我也可以与其他作用域 bean(例如:)一起使用@Dependent吗?

我记得使用 CDI 方法阅读了一些关于潜在内存泄漏的内容,但不明白如何或为什么会出现这种情况。

Sil*_*rus 7

两种方法产生相似的结果,但是有两个主要区别。

  • CDI.current() 是你可以在你不能简单的地方的东西 @Inject BeanManager
    • 这只是一种从非 cdi 托管对象获取 CDI 实例的方法
  • Instance.get()不接受CreationalContext参数,而BM.getReference()
    • 这是一种方式,当使用关键的区别Instance时,CreationalContext由容器管理-你不必在意它,尤其是关于释放的背景下。如果您正在使用,BM.getReference()您首先需要获取该上下文,这通常意味着创建它,并且一旦您完成使用它,您就有责任释放它。


Meh*_*hmi 5

我们使用这些方法在您的非 CDI 代码中访问 CDI。在 CDI 代码中,我们可以注入 BeanManager 和您的 bean。

JNDI 查找用于 CDI 1.0。在 CDI 1.1 之后,我们应该使用 CDI 类及其静态方法。

http://www.next-presso.com/2016/02/cdi-the-spi-who-loved-me/

在 CDI 1.0 中,您必须访问 CDI bean 图的唯一解决方案是从 JNDI 检索 BeanManager ......这种冗长证明了 BeanManager 是高级 CDI 工具,允许对 CDI 回声系统进行非常基本的操作。如果您只想访问实例,这显然不是最佳解决方案。这就是为什么在 CDI 1.1 中我们引入了抽象 CDI 类,它使用 Java Service Loader 从实现中检索具体的 CDI 类。... 检索实例变得如此简单

CDI<Object> cdi = CDI.current();
MyService service = cdi.select(MyService.class).get();
Run Code Online (Sandbox Code Playgroud)