В CDI есть псевдо-область видимости @ApplicationScoped
и ( javax.inject
) @Singleton
. В чем разница между ними? Помимо того, что @ApplicationScoped
проксируется, и @Singleton
нет.
Могу я просто поменять свой @Singleton
bean на @ApplicationScoped
? Может ли @ApplicationScoped
bean иметь два (или более) экземпляра?
@ApplicationScoped
и@Singleton
в разделе 5.4 (стр. 36).Ответы:
@Singleton
не является частью спецификации CDI. Это часть EJB иjavax.inject
(JSR-330). В спецификации не упоминается, каково его поведение, поэтому вы можете полагаться только на то, что написано в документации Weld.источник
@Singleton
. Это показано только на одном примере без пояснений. Это правда, что CDI полагаетсяjavax.inject
, но, строго говоря, это не часть спецификации CDI. Тем не менее, я немного поправил свой ответ.вкратце: вы даже можете смешивать это (
@Singleton
и@ApplicationScoped
), и это имеет смысл в некоторых сценариях. (и работает как положено в моем!)В дополнение к другим ответам я хотел бы добавить еще несколько моментов для пояснения в реальных сценариях.
Для меня этот вопрос возник из статьи « Как заставить bean-компонент с областью действия приложения создавать экземпляр при запуске приложения?» В некоторой дискуссии я заявил об этом и пока не могу найти веского аргумента против этого:
(спорные, но не окончательные) аргументы (с моей точки зрения) против этого до сих пор: (@BalusC и все другие: я бы хотел, чтобы они были убедительными, но если нет, то приведенное выше может быть верным, и тем не менее аргументы могут по-прежнему помогают читателю понять различия / преимущества / недостатки / плохие / хорошие практики)
EJB против управляемого компонента
но:
... что все еще верно в моем случае.
Singleton EJB против компонента с областью действия приложения
Блокировка
но:
(Я не вижу здесь кувалду - извините ...) Хорошо знать значения блокировки по умолчанию (я не знал об этом), но это снова кажется неверным: Oracle Java EE 6 Tutorial on Managing Concurrent Access in a Сессионный компонент Singleton
источник
Обычно, когда вы хотите иметь только один экземпляр какого-либо объекта, вам, вероятно, следует использовать
@ApplicationScoped
аннотацию - такой объект проксируется и, таким образом, даже может быть правильно сериализован прямо из коробки.С другой стороны, также есть много случаев, когда вам нужен только один экземпляр класса, но такой класс не может быть проксирован (например, из-за того, что он окончательный) - тогда
@Singleton
это спасение. ПотомуSingleton
что это псевдо-область видимости и не проксируется, как любая "нормальная" область видимости.источник
@Singleton
в JSR-299 относится к сеансовым компонентам Singleton (javax.ejb.Singleton
неjavax.inject.Singleton
), а не к управляемым компонентам JSR-299 во встроенной области, называемой Singleton.Вы можете найти на своем сервере
@ApplicationScoped
один на EAR или один на WAR / EJB-JAR, поскольку это не ясно в спецификации, но вы определенно не должны ожидать, что это будет один на JVM.источник
Есть еще одно отличие:
@Singleton
компонент не определяет аннотации, так какSingleton
область видимости не является нормальной областью. Затем@ApplicationScoped
- аннотации, определяющие компонент.Согласно спецификации CDI 1.1: когда приложение находится в режиме обнаружения = аннотировано, Weld не идентифицирует bean-компоненты
@Singleton
и не загружает ихисточник
Одно из основных различий в том, что вы можете написать свой класс с конструктором по умолчанию, имеет модификатор частного доступа при использовании
javax.inject.Singleton
, но ваш класс должен иметь конструктор по умолчанию с как минимум модификатором доступа по умолчанию при использовании,javax.enterprise.context.ApplicationScoped
и этоJBOSS 6.1 GA Final
реализацияисточник