Instance#get() возвращает тот же экземпляр для бинов @ApplicationScoped в CDI?
Если @ApplicationScoped
боб получается через Instance<T>#get()
делает ли последующие звонки get()
использовать один и тот же экземпляр (я точно знаю, ProxyObject
используется)?
2 ответа
Если
@ApplicationScoped
боб получается черезInstance<T>#get()
делает ли последующие звонкиget()
повторно использовать тот же экземпляр?
Краткий ответ: Да, прокси того же экземпляра будет возвращен. Продолжайте читать для более подробной информации.
От Instance<T>
документация:
Наследственный
Provider.get()
Метод возвращает контекстные ссылки для уникального компонента, который соответствует требуемому типу и требуемым квалификаторам [...]
Смотрите следующую цитату из спецификации CDI, которая определяет контекстную ссылку:
Внедренная ссылка или ссылка, полученная программным поиском, обычно является контекстной ссылкой, определенной посредством контекстной ссылки для компонента.
Контекстная ссылка на bean-компонент с нормальной областью действия, как определено в " Обычных областях видимости и псевдоскопах", не является прямой ссылкой на контекстный экземпляр bean-компонента (объект, возвращаемый
Contextual.create()
). Вместо этого контекстная ссылка является прокси- объектом клиента. Клиентский прокси реализует / расширяет некоторые или все типы bean-компонентов bean-компонента и делегирует все вызовы методов текущему экземпляру (как определено в обычных и псевдоскопических областях) bean-компонента.[...]
Что касается нормальных областей применения, в спецификации CDI упоминается следующее:
Контексты с обычными областями действия должны подчиняться следующему правилу:
Предположим, что бобы 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
Да. clientproxy выбирает экземпляр из контекста области приложения.
https://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/Instance.html
Экземпляр #get() возвращает контекстные ссылки