Instance#get() return 是否与 CDI 中的 @ApplicationScoped bean 相同?

Does Instance#get() return the same instance for @ApplicationScoped beans in CDI?

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

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

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

Instance#get() returns 上下文引用

If an @ApplicationScoped bean is obtained through Instance<T>#get(), does subsequent calls to get() reuse the same instance?

简短回答: 是的,将返回同一实例的 代理。继续阅读以了解更多详情。


来自 Instance<T> 文档:

The inherited Provider.get() method returns a contextual references for the unique bean that matches the required type and required qualifiers [...]

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

5.4. Client proxies

An injected reference, or reference obtained by programmatic lookup, is usually a contextual reference as defined by Contextual reference for a bean.

A contextual reference to a bean with a normal scope, as defined in Normal scopes and pseudo-scopes, is not a direct reference to a contextual instance of the bean (the object returned by Contextual.create()). Instead, the contextual reference is a client proxy object. A client proxy implements/extends some or all of the bean types of the bean and delegates all method calls to the current instance (as defined in Normal scopes and pseudo-scopes) of the bean.

[...]

关于普通作用域CDI specification提到了以下内容:

Contexts with normal scopes must obey the following rule:

Suppose beans A, B and Z all have normal scopes. Suppose A has an injection point x, and B has an injection point y. Suppose further that both x and y resolve to bean Z according to the rules of typesafe resolution. If a is the current instance of A, and b is the current instance of B, then both a.x and b.y refer to the same instance of Z. This instance is the current instance of Z.

All normal scopes must be explicitly declared @NormalScope, to indicate to the container that a client proxy is required.

如果您检查 @ApplicationScoped annotation, you'll find out it's annotated with @NormalScope:

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