我发现有两种一般的方法可以通过BeanManager
仅以aBean<T>
开头(基于来创建Class<T>
)来获取自动创建的CDI托管bean实例:
通过BeanManager#getReference()
,通常在摘要中显示:
Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class));
TestBean testBean1 = (TestBean) beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean));
通过Context#get()
,在代码段中较少显示:
Bean<TestBean> bean = (Bean<TestBean>) beanManager.resolve(beanManager.getBeans(TestBean.class));
TestBean testBean2 = beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean));
实际上,它们的作用完全相同:返回对当前CDI管理的bean实例的代理引用,并在范围内尚不存在时自动创建bean实例。
但是它们的做法有所不同:BeanManager#getReference()
总是创建一个全新的代理实例,而Context#get()
如果以前已经创建过,则重用现有的代理实例。当在现有TestBean
实例的操作方法中执行以上代码时,这是显而易见的:
System.out.println(testBean1 == testBean2); // false
System.out.println(testBean1 == this); // false
System.out.println(testBean2 == this); // true
该的javadoc的Context#get()
是非常明确的在此:
返回某个特定上下文类型的现有实例,或者通过调用Contextual.create(CreationalContext)创建一个新实例并返回该新实例。
而javadoc中的BeanManager#getReference()
不在此明确就够了:
获取特定bean和特定bean类型的上下文引用。
这让我感到困惑。您何时使用一个或另一个?对于这两种方式,无论如何您都需要一个Bean<T>
实例,从中可以很容易地获得bean类和bean作用域,这是附加参数。我无法想象为什么在这种特定情况下需要从外部提供它们。
我可以想象这Context#get()
会提高内存效率,因为它不必不必要地创建另一个引用同一基础bean实例的代理实例,而只是查找并重用现有的代理实例。
这使我提出以下问题:什么时候BeanManager#getReference()
比有用Context#get()
?它通常在摘要中显示,并且经常被建议作为解决方案,但是即使已存在一个新代理,它也不必要地创建了一个新代理。
beanManager#getReference为您提供了客户端代理的新实例,但是客户端代理会将方法调用转发到特定上下文的当前上下文实例。一旦获得代理并将其保留,该方法调用将在当前实例(例如当前请求)上调用。如果上下文实例不可序列化,这也很有用-客户端代理将是并且将在反序列化之后重新连接。
BeanManager#getContext在没有客户端代理的情况下获取目标实例。您可能仍会在类名称中看到Weld的代理,但这是提供拦截和修饰的增强子类。如果未拦截或修饰该bean,则它将是给定bean的普通实例。
通常(1)更合适,除非您有一个特殊的用例,在这种情况下您需要直接访问目标实例(例如,访问其实例的字段)。
1)BeanManager#getReference将返回一个“上下文引用”,以及该bean的常规作用域代理。如果一个豆有@SessionScoped
as
@SessionScoped User user;
然后,上下文引用用户将为每个调用“指向”当前会话的相应用户实例(“上下文实例”)。user.getName()
来自两个不同的Web浏览器的两个不同的调用将为您提供不同的答案。
2)Context#get()将返回内部的``上下文实例'',而没有普通的作用域代理,这通常是用户不应自称的。如果您User user
以这种方式获得for“ Bob”并将其存储在@ApplicationScoped
Bean或静态变量中,则它将始终保持用户“ Bob”的身份-即使来自其他浏览器的Web请求也是如此!您将获得一个直接的,非代理的实例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句