Ответ 1
@Singleton
не входит в спецификацию CDI. Он является частью EJB и javax.inject
(JSR-330). В спецификации не упоминается, каково его поведение, поэтому вы можете полагаться только на то, что написано в документации Weld.
В CDI есть псевдоним @ApplicationScoped
и (javax.inject
) @Singleton
. В чем разница между ними? Помимо того, что @ApplicationScoped
проксирован, а @Singleton
- нет.
Можно ли изменить мой @Singleton
bean на @ApplicationScoped
? Может ли @ApplicationScoped
bean иметь два (или более) экземпляра?
@Singleton
не входит в спецификацию CDI. Он является частью EJB и javax.inject
(JSR-330). В спецификации не упоминается, каково его поведение, поэтому вы можете полагаться только на то, что написано в документации Weld.
@Singleton
в JSR-299 относится к сеансу Singleton beans (javax.ejb.Singleton
, not javax.inject.Singleton
), а не JSR-299 beans во встроенной области, называемой Singleton.
Вы можете найти на своем сервере, что @ApplicationScoped
- это один за EAR или один на WAR/EJB-JAR, поскольку это не ясно в спецификации, но вы не должны ожидать, что он будет одним на JVM.
: вы можете даже смешивать его (@Singleton
и @ApplicationScoped
), и это имеет смысл в некоторых сценариях.
(и работает так, как ожидалось в моей!)
В дополнение к другим ответам до сих пор я хотел бы добавить еще несколько моментов для разъяснения в реальных сценариях.
Для меня этот вопрос возник из Как принудительно создать приложение bean для приложения при запуске приложения? В некоторых обсуждениях я заявил об этом и не могу найти до сих пор действительного аргумента:
Во многих реальных сценариях/настройках я бы сказал, что трудно определенно сказать - с абстрактной/моделирующей точки зрения - независимо от того, что-то (или будет/должно рассматриваться как) EJB или управляемый приложением bean.
(спорные, но не убедительные) аргументы (с моей точки зрения) против него до сих пор: (@BalusC и все остальные: я бы хотел, чтобы они были неопровержимыми, но если нет, то это может быть правдой, и тем не менее аргументы могут помочь читателю получить различия/преимущества/недостатки/плохие/хорошие практики)
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 [...]
... который сохраняется в моем случае.
BalusC: одноэлементный EJB не совпадает с областью приложения bean. Одноэлементный EJB блокируется чтением/записью и, следовательно, потенциально неэффективен/сверхконвертирован для заданной вами задачи. Короче говоря: возьмите хорошую книгу Java EE и научитесь использовать правильный инструмент для работы. В одном направлении определенно не так. То, что это работает, не означает, что это правильный инструмент. Кувалда способна закрепить винт, но это не обязательно правильный инструмент:)
а
(Я не вижу кувалду здесь - извините...) Хорошо знать блокировки по умолчанию (я не знал об этом), но это кажется неверным снова: Oracle Java EE 6 Учебное пособие по управлению параллельным доступом в сеанс Singleton Bean
При создании сеанса singleton bean одновременный доступ к бизнес-методам синглтонов можно контролировать двумя способами: управляемым контейнером concurrency и bean -managed concurrency. [...]
Хотя по умолчанию синглеты используют управляемый контейнером concurrency, аннотация @ConcurrencyManagement (CONTAINER) может быть добавлена на уровне класса singleton, чтобы явно установить тип управления concurrency
Есть еще одна разница:
@Singleton
не bean определяет аннотации, поскольку область Singleton
не является нормальной областью.
Тогда @ApplicationScoped
является bean, определяющим аннотации.
С спецификацией CDI 1.1: когда приложение в режиме обнаружения = аннотировано, Weld не идентифицирует beans с @Singleton
и не загружает этот
Обычно, когда вы хотите иметь только один экземпляр какого-либо объекта, вы, вероятно, должны использовать аннотацию @ApplicationScoped
- такой объект проксирован и, следовательно, даже может быть правильно сериализован из коробки.
С другой стороны, есть также много случаев, когда вам нужен только один экземпляр класса, но такой класс не может быть проксирован (например, из-за того, что он окончательный) - тогда @Singleton
является спасением. Поскольку Singleton
является псевдообъектом и не проксируется, как любая "нормальная" область.
Одно из главных отличий, которое вы можете написать своему классу со стандартным подрядчиком, имеет модификатор частного доступа при использовании javax.inject.Singleton
, но при использовании javax.enterprise.context.ApplicationScoped
у вашего класса должен быть стандартный подрядчик с модификатором доступа по умолчанию, хотя это JBOSS 6.1 GA Final
> реализация