在JEE / CDI的上下文中,当我需要从方法中静态检索CDI托管bean时,通常会使用CDI静态函数。例如:
MyBean myBean = CDI.current().select( MyBean.class ).get()
但是,据我所知,另一种等效的实现方法是使用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);
因此,除了使用CDI.current()
方法编写的代码要少得多之外,使用它还有什么区别?似乎恢复使用BeanManager
是一种更为复杂(并且可能容易出错?)的方法。从功能的角度来看,改用CDI.current()
方法有什么缺点吗? CDI...select()
仅适用于@ApplicationScope
bean吗?还是可以与其他作用域内的bean(例如@Dependent
)一起使用?
我记得使用CDI方法阅读了有关潜在内存泄漏的内容,但不了解这种情况如何或为什么发生。
答案 0 :(得分:1)
我们使用这些方法以您的非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();
答案 1 :(得分:1)
两种方法的结果相似,但是有两个主要区别。
CDI.current()
是您可以做的事,而您不能简单地@Inject BeanManager
。
Instance.get()
不使用CreationalContext
参数,而BM.getReference()
则使用。
Instance
时,CreationalContext
由容器管理-您不必关心它,尤其是释放上下文。如果您使用的是BM.getReference()
,则首先需要获取该上下文,这通常意味着创建它,并使您有责任在完成使用后也将其释放。