В чем разница между областями @ApplicationScoped и @Singleton в CDI? - PullRequest
82 голосов
/ 29 декабря 2010

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

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

Ответы [ 6 ]

24 голосов
/ 30 декабря 2010

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

16 голосов
/ 20 января 2016

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

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

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

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

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

EJB против управляемого боба

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

но:

me : Я думаю, что вы не совсем правы и преувеличиваете значение / использование, и это кажется мне спорным. 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) может быть добавлена ​​на уровне класса синглтона для явной установки типа управления параллелизмом

9 голосов
/ 28 ноября 2015

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

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

9 голосов
/ 08 января 2011

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

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

4 голосов
/ 22 апреля 2016

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

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

2 голосов
/ 15 сентября 2014

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

...