В чем разница между областями @ApplicationScoped и @Singleton в CDI?

В CDI есть @ApplicationScoped и (javax.inject) @Singleton псевдо-сфера. В чем разница между ними? Помимо того, что @ApplicationScoped прокси и @Singleton не является.

Могу ли я просто изменить свой @Singleton фасоль для @ApplicationScoped? Можно @ApplicationScoped бин есть два (или более) экземпляров?

7 ответов

@Singleton не является частью спецификации CDI. Это часть EJB и javax.inject (JSR-330). В спецификации не указано, каково его поведение, поэтому вы можете полагаться только на то, что написано в документации по сварке.

короче: можно даже смешать ( @Singleton а также @ApplicationScoped ) и это имеет смысл в некоторых сценариях. (и работает как положено у меня!)

В дополнение к другим ответам на данный момент я хотел бы добавить еще несколько моментов для разъяснения в реальных сценариях.

Для меня этот вопрос разработан на основе Как заставить бин области приложения создать экземпляр при запуске приложения? В какой-то дискуссии я заявил об этом и пока не могу найти веских аргументов против этого:

Во многих реальных сценариях / установках я бы сказал, что трудно определенно сказать - с абстрактной / модельной точки зрения - является ли что-то (или станет / будет рассматриваться как) EJB-компонентом или управляемым компонентом в области приложения.

(спорные, но не окончательные) аргументы (с моей точки зрения) до сих пор против этого: (@BalusC и все остальные: я бы хотел, чтобы они были убедительными, но если нет, то вышеизложенное может быть верным, и, тем не менее, аргументы могут все еще помогите читателю получить различия / преимущества / недостатки / плохие / хорошие практики)

EJB против Управляемого Бина

BalusC: Это EJB, а не управляемый бин, что совсем другое. EJB-компоненты работают в бэкэнде, а управляемые bean-компоненты - во внешнем EJB также работают в транзакционном контексте. [...] Вы просто перепутали корпоративные бины с управляемыми бинами, и я только что указал на это.

но:

Я: Я думаю, что вы не совсем правильно и преувеличиваете значение / использование, и это выглядит спорным для меня. http://en.wikipedia.org/wiki/Enterprise_JavaBeans

Enterprise JavaBeans (EJB) - это управляемое серверное программное обеспечение для модульного построения корпоративного программного обеспечения и один из нескольких API Java. EJB - это программный компонент на стороне сервера, который инкапсулирует бизнес-логику приложения.

Типы корпоративных бобов

Сессионные компоненты [3], которые могут быть "Stateful", "Stateless" или "Singleton" [...]

Бобы, управляемые сообщениями [...]

... что все еще верно в моем случае.

Синглтон EJB против приложения Scoped Bean

Блокировка

BalusC: одноэлементный EJB - это не то же самое, что бин в области приложения. Одноэлементный EJB блокируется на чтение / запись и, таким образом, потенциально неэффективен / чрезмерен для задачи, которую вы имели в виду. Короче говоря: возьмите хорошую книгу по Java EE и научитесь использовать правильный инструмент для работы. Один путь определенно не другой. То, что это работает, не означает, что это правильный инструмент. Кувалда способна закрепить винт, но это не обязательно правильный инструмент для этого:)

но:

(Я не вижу кувалды здесь - извините...) Хорошо знать значения по умолчанию для блокировки (я не знал об этом), но это снова кажется неправильным: учебное руководство по Oracle Java EE 6 по управлению параллельным доступом в Синглтон сессионный бин

При создании одноэлементного сессионного компонента одновременный доступ к бизнес-методам синглтона можно контролировать двумя способами: параллелизм, управляемый контейнером, и параллелизм, управляемый бином. [...]

Хотя по умолчанию в синглетах используется управляемый контейнером параллелизм, аннотация @ConcurrencyManagement(CONTAINER) может быть добавлена ​​на уровне класса синглтона для явной установки типа управления параллелизмом.

Обычно, когда вы хотите иметь только один экземпляр какого-либо объекта, вы, вероятно, должны использовать @ApplicationScoped аннотация - такой объект проксируется и, таким образом, может быть даже должным образом сериализован из коробки.

С другой стороны, есть также много случаев, когда вы хотите только один экземпляр класса, но такой класс не может быть прокси (например, из-за того, что он последний) - тогда @Singleton спасение Так как Singleton является псевдоскопом и не передается как любая "нормальная" область видимости.

@Singleton в JSR-299 ссылается на сессионные компоненты Singleton (javax.ejb.Singletonне javax.inject.Singleton), а не управляемые bean-компоненты JSR-299 во встроенной области действия, называемой Singleton.

Вы можете найти на своем сервере, что @ApplicationScoped это один на EAR или один на WAR/EJB-JAR, поскольку это неясно в спецификации, но вы не должны ожидать, что он будет один на JVM.

Есть еще одно отличие:@Singleton не является компонентом, определяющим аннотации, так как Singleton сфера не является нормальной областью. затем @ApplicationScoped это бин, определяющий аннотации.

Со спецификацией CDI 1.1: когда приложение в режиме обнаружения = аннотировано, Weld не идентифицирует компоненты с @Singleton и не загружается это

Одно из основных отличий, которое вы можете написать для своего класса с подрядчиком по умолчанию, заключается в использовании модификатора частного доступа javax.inject.Singleton, но ваш класс должен иметь подрядчика по умолчанию с по крайней мере модификатором доступа по умолчанию при использовании javax.enterprise.context.ApplicationScoped а это JBOSS 6.1 GA Final реализация

Я знаю, что это старый пост, но мне часто задают этот вопрос.

ИМХО, заходим в источник -> https://www.javadoc.io/doc/jakarta.enterprise/jakarta.enterprise.cdi-api/latest/jakarta/enterprise/context/ApplicationScoped.html

https://www.javadoc.io/doc/jakarta.inject/jakarta.inject-api/latest/jakarta/inject/Singleton.html

https://quarkus.io/guides/cdi-reference#lazy_by_default предоставляет хороший справочник, сравнивающий их с точки зрения практического использования.

(Также полезно отметить, что в этом последнем случае Quarkus создает конструктор без аргументов для вас, чтобы удовлетворить требованиям для bean-компонентов CDI, поэтому вам не нужно делать DIY или Lombok-it.)

Другие вопросы по тегам