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

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

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

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

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

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

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

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

EJB vs. Управляемый Bean

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

а

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

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

Типы предприятий Beans

Сессия beans [3], которая может быть либо "Stateful", "Stateless", либо "Singleton" [...]

Message Driven beans [...]

... который сохраняется в моем случае.

Singleton EJB vs. Application Scoped Bean

Блокировка

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

а

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

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

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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