В CDI есть псевдо-скоп @ ApplicationScoped
и (javax.inject
) @ Singleton
. В чем разница между ними? Помимо того факта, что @ApplicationScoped
является прокси, а @ Singleton
- нет.
Могу ли я просто изменить свой боб @ Singleton
на @ ApplicationScoped
? Может ли боб @ ApplicationScoped
иметь два (или более) экземпляра?
@ Singleton
не является частью спецификации CDI. Он является частью EJB и javax.inject
(JSR-330). В спецификации не упоминается, каково его поведение, поэтому вы можете полагаться только на то, что написано в документации Weld.
короче: вы даже можете смешать его (@ Singleton
и @ ApplicationScoped
), и это имеет смысл в некоторых сценариях.
(и работает, как и ожидалось в моем!)
В дополнение к другим ответам я хотел бы добавить еще несколько моментов для разъяснения в реальных сценариях.
Для меня этот вопрос возник из Как заставить боб с аппликацией создавать экземпляры при запуске приложения? В какой-то дискуссии я заявил об этом и пока не могу найти веского аргумента против этого:
Во многих реальных сценариях / настройках я бы сказал, что это сложно определенно скажите - с абстрактной / моделирующей точки зрения - будь то что-то является (или станет / будет рассматриваться как) EJB или управляемым бобом с кодировкой приложения.
(спорные, но не окончательные) аргументы (с моей точки зрения) против этого до сих пор: (@BalusC и все остальные: я хотел бы, чтобы они были убедительными, но если нет, то вышеизложенное может быть верным, и, тем не менее, аргументы все еще могут помочь читателю получить различия / преимущества / недостатки / плохие / хорошие практики)
- HalusC *: это EJB, а не управляемый боб, который совсем другой. EJB работают в бэкэнде и управляют бобами в фронтоне. EJB также работают в транзакционном контексте. [...] Вы просто перепутали корпоративные бобы с управляемыми бобами, и я просто указал на это.
но:
- me *: Я думаю, что вы не совсем правы и преувеличиваете значение / использование, и это выглядит для меня спорным. http://en.wikipedia.org/wiki/Enterprise_JavaBeans
Enterprise JavaBeans (EJB) - это управляемое серверное программное обеспечение для модульного построения корпоративного программного обеспечения и один из нескольких API Java. EJB - это программный компонент на стороне сервера, который инкапсулирует бизнес-логику приложения.*
Типы корпоративных бобов *
Сеанс Бобы [3], которые могут быть «Stateful», «Stateless» или «Singleton» [...] *
Ведомые бобы [...] *
что все еще верно в моем случае...
- HalusC *: однотонный EJB - это не то же самое, что фасоль с шипами. Синглтон EJB заблокирован для чтения / записи и, следовательно, потенциально неэффективен / чрезмерно реализован для задачи, которую вы имели в виду. Короче говоря: возьмите хорошую книгу по Java EE и научитесь использовать правильный инструмент для работы. Один путь определенно не другой. То, что это работает, не означает, что это правильный инструмент. Кувалда способна закрепить винт, но это не обязательно правильный инструмент для этого :)
но:
(Я не вижу кувалду здесь - извините ...) Полезно знать значения по умолчанию блокировки (я не знал об этом), но это снова кажется неправильным: Oracle Java EE 6 Tutorial on Управление одновременным доступом в одиночном сеансе боба
- При создании однотонного сеанса боба одновременный доступ к бизнес-методам синглета можно контролировать двумя способами: параллелизмом с управлением контейнером и параллелизмом с управлением бобами. [...] *
- Хотя по умолчанию одиночные используют управляемый контейнером параллелизм, аннотация @ConcurrencyManagement (CONTAINER) может быть добавлена на уровне класса однотона, чтобы явно установить тип управления параллелизмом *
@ Singleton
в JSR-299 относится к сессионным бобам Singleton (javax.ejb.Singleton
, а не javax.inject.Singleton
), а не к фасоли JSR-299, управляемым во встроенной области, называемой Singleton.
На вашем сервере вы можете обнаружить, что @ ApplicationScoped
является одним на EAR или одним на WAR / EJB-JAR, поскольку это не ясно в спецификации, но вы определенно не должны ожидать, что он будет одним на JVM .
Обычно, когда вы хотите иметь только один экземпляр какого-либо объекта, вам, вероятно, следует использовать аннотацию @ ApplicationScoped
- такой объект является прокси-сервером и, таким образом, может даже быть правильно сериализован вне коробки.
С другой стороны, есть также много случаев, когда вам нужен только один экземпляр класса, но такой класс не может быть прокси (например,. из-за того, что он окончательный) - тогда @ Singleton
- спасение. Потому что «Singleton» является псевдо-сферой и не является прокси-фором, как любой «нормальный» прицел.
Есть еще одно отличие:
@ Singleton
не является бин, определяющим аннотации, так как область Singleton
не является нормальной областью.
Тогда @ ApplicationScoped
- это аннотации, определяющие бобы.
Со спецификацией CDI 1.1: при применении в Discovery-Mode = аннотировано Weld не идентифицирует бобы с @ Singleton
и не загружает их
Одно из основных отличий, которое вы можете написать в своем классе с помощью конструктора по умолчанию, имеет модификатор частного доступа при использовании javax.inject.Singleton
, но ваш класс должен иметь конструктор по умолчанию с модификатором доступа по крайней мере по умолчанию при использовании javax.enterprise.context. ApplicationScoped
, и это JBOSS 6.1 GA Final
реализация