如果@ApplicationScoped通过 获取 bean Instance<T>#get(),后续调用是否会get()重用同一实例(我确信ProxyObject使用了相同的实例)?
如果
@ApplicationScoped通过 获取beanInstance<T>#get(),后续调用是否会get()重用同一个实例?
简短回答:是的,将返回同一实例的代理。继续阅读以了解更多详细信息。
从Instance<T>文档中:
继承的
Provider.get()方法返回与所需类型和所需限定符匹配的唯一 bean 的上下文引用 [...]
请参阅CDI 规范中定义上下文参考的以下引用:
注入的引用或通过编程查找获得的引用通常是上下文引用,如bean 的上下文引用所定义。
对具有正常作用域的 bean 的上下文引用(如正常作用域和伪作用域中所定义)不是对该 bean 的上下文实例(由 返回的对象
Contextual.create())的直接引用。相反,上下文引用是客户端代理对象。客户端代理实现/扩展 bean 的部分或全部 bean 类型,并将所有方法调用委托给bean 的当前实例(如普通作用域 和 伪作用域中所定义)。[...]
关于正常范围,CDI规范提到以下内容:
具有正常作用域的上下文必须遵守以下规则:
假设 bean A、B 和 Z 都有正常作用域。假设A有一个注入点x,B有一个注入点y。进一步假设 x 和 y 都根据类型安全解析规则解析为 bean Z。如果 a 是 A 的当前实例,b 是 B 的当前实例,则 ax 和 by 都引用 Z 的同一个实例。该实例是 Z 的当前实例。
所有普通范围都必须显式声明
@NormalScope,以向容器指示需要客户端代理。
如果您检查@ApplicationScoped注释,您会发现它的注释为@NormalScope:
@Target(value = { TYPE, METHOD, FIELD })
@Retention(value = RUNTIME)
@Documented
@NormalScope
@Inherited
public @interface ApplicationScoped
Run Code Online (Sandbox Code Playgroud)