简体   繁体   中英

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

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

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

Short answer: Yes, a proxy of same instance will be returned. Keep reading for more details.


From the Instance<T> documentation:

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

See the following quote from the CDI specification which defines contextual reference :

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.

[...]

Regarding normal scopes , the CDI specification mentions the following:

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 ax and by 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.

If you inspect the @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

Yes. clientproxy selects the instance from the applicationscope context.

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

Instance#get() returns a contextual references

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM