Instance#get()是否为CDI中的@ApplicationScoped bean返回相同的实例?

时间:2018-10-08 08:55:35

标签: java cdi

如果通过@ApplicationScoped获得了Instance<T>#get() bean,对get()的后续调用是否会重用同一实例(我确定使用相同的ProxyObject)? / p>

2 个答案:

答案 0 :(得分:3)

  

如果通过@ApplicationScoped获得了Instance<T>#get() bean,对get()的后续调用会重用同一实例吗?

简短答案:是的,将返回相同实例的 proxy 。继续阅读以获取更多详细信息。


摘自Instance<T>文档:

  

继承的Provider.get()方法返回与所需类型和限定符匹配的唯一bean的上下文引用[...]

请参见CDI specification中的以下引文,该引文定义了上下文引用

  

5.4. Client proxies

     

注入的引用或通过程序化查找获得的引用通常是Contextual reference for a bean定义的上下文引用

     

Normal scopes and pseudo-scopes中定义的对具有正常范围的bean的上下文引用不是对bean上下文实例的直接引用(Contextual.create()返回的对象)。相反,上下文引用是客户端代理对象。客户端代理实现/扩展了该bean的部分或全部bean类型,并将所有方法调用委托给该bean的当前实例(在Normal scopes and pseudo-scopes中定义)。

     

[...]

关于正常范围CDI specification提及以下内容:

  

具有正常作用域的上下文必须遵守以下规则:

     

假定豆A,B和Z都具有正常范围。假设A有一个注入点x,B有一个注入点y。进一步假设x和y都根据类型安全解析的规则解析为beanZ。如果a是A的当前实例,b是B的当前实例,则a.x和b.y都引用Z的同一实例。该实例是Z的当前实例。

 
  

必须将所有常规作用域明确声明为@NormalScope,以向容器指示需要客户端代理。

如果检查@ApplicationScoped批注,则会发现它带有@NormalScope批注:

@Target(value = { TYPE, METHOD, FIELD })
@Retention(value = RUNTIME)
@Documented
@NormalScope
@Inherited
public @interface ApplicationScoped

答案 1 :(得分:1)

是的。 clientproxy从applicationscope上下文中选择实例。

https://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/Instance.html

Instance#get()返回上下文引用