У чому різниця між сферами @ApplicationScoped та @Singleton у CDI?


96

У CDI існує псевдообсяг @ApplicationScopedі ( javax.inject) @Singleton. Яка різниця між ними? Окрім того, що @ApplicationScopedпроксі-сервер є, і @Singletonні.

Чи можу я просто змінити свою @Singletonквасолю на @ApplicationScoped? Чи може @ApplicationScopedbean мати два (або більше) екземпляри?


12
Чи читали ви посилання на зварювання ? Є певне пояснення практичних відмінностей між розділом 5.4 @ApplicationScopedта @Singletonйого розділом (с. 36).
brandizzi

1
до якої сфери дії Singleton ви маєте на увазі - javax.ejb чи javax.inject?
Джон Амент

Відповіді:


30

@Singletonне є частиною специфікації CDI. Це частина EJB та javax.inject(JSR-330). У специфікації не згадується, якою є її поведінка, тому ви можете покладатися лише на те, що написано в документації до зварювання.


11
Це не правда. Є анотація javax.inject.Singleton. Це частина CDI. Перевірте тут: docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/…
amorfis

5
@amorphis - переді мною специфікація CDI. Я навіть реалізував його частини, і в ньому нічого не згадується @Singleton. Це показано лише в одному прикладі, без пояснень. Це правда, що CDI покладається javax.inject, але, строго кажучи, це не є частиною специфікації CDI. Тим не менш, я трохи виправив свою відповідь.
Божо

17

коротше: ви навіть можете змішувати це ( @Singletonі @ApplicationScoped), і це має сенс у деяких сценаріях. (і працює, як очікується в моєму!)

Додатково до інших відповідей поки що я хотів би додати ще кілька пунктів для роз'яснення в реальних сценаріях.

Для мене це запитання розроблено на тему Як змусити компонент з масштабом програми екземпляром під час запуску програми? У ході певної дискусії я заявив це і поки що не можу знайти вагомого аргументу проти цього:

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

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

EJB проти керованого компонента

BalusC : Це EJB, а не керований бін, який зовсім інший. EJB працюють у серверній системі, а керовані компоненти - в інтерфейсі. EJB також працюють у транзакційному контексті. [...] Ви щойно переплутали корпоративні боби з керованими бобами, і я просто вказав на це.

але:

я : Я думаю, ви не зовсім коректні і завищуєте значення / вживання, і це здається мені дискусійним. http://en.wikipedia.org/wiki/Enterprise_JavaBeans

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

Види Enterprise Beans

Сеансові боби [3], які можуть бути або "Державними", "Без громадянства" або "Сінглтон" [...]

Боби, що керуються повідомленнями [...]

... що досі справедливо в моєму випадку.

Singleton EJB проти Bean із сферою застосування

Блокування

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

але:

(Я не бачу тут кувалди - вибачте ...) Добре знати за замовчуванням заблоковані (я про це не знав), але це, схоже, знову неправильно: Підручник з керування паралельним доступом у Oracle Java EE 6 Сінгл Сеанс Бін

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

Хоча за замовчуванням одиночні використовують паралельно керовану контейнером, анотацію @ConcurrencyManagement (CONTAINER) може бути додана на рівні класу одиночної, щоб явно встановити тип управління паралельністю


Зварювання не забавляється змішуванням: Виняток під час завантаження програми: Помилка визначення CDI: WELD-000046: У публічній програмі [EnhancedAnnotatedTypeImpl] може бути вказано щонайбільше одну сферу застосування Singleton MyClass. Використання javax.inject.Singleton.
sgflt

12

Зазвичай, коли ви хочете мати лише один екземпляр якогось об'єкта, вам, мабуть, слід використовувати @ApplicationScopedанотацію - такий об'єкт проксі-код і, отже, навіть може бути належним чином серіалізований нестандартно.

З іншого боку, є також багато випадків, коли вам потрібен лише один екземпляр класу, але такий клас не може бути проксі-сервером (наприклад, через остаточність) - тоді @Singletonце порятунок. Тому що Singletonє псевдосферою і не проксі-проксі, як будь-який "звичайний" обсяг.


Я голосую за це, бо це дуже незрозуміло. Я кодую Java EE вже п’ять років, беру підручники та читаю книги, але я не маю чіткого уявлення про те, що ви маєте на увазі, коли говорите „такий об’єкт проксі-сервером”, „навіть може бути належним чином серіалізований” та „псевдо- область дії ". Я хотів би знати, що це означає, оскільки це схоже на те, що ви знаєте, про що говорите, але, як написано, я не уявляю, що ваша відповідь допоможе більшості розробників Java EE.
DavidS

2
Тим не менш, я знаю, що EJB проксі-сервери. Моя плутанина частково пов’язана з різницею, яку ви робите для одиноких.
DavidS

9

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

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


7

Є ще одна відмінність: @Singletonанотації не визначають компонент, оскільки Singletonобласть дії не є звичайною сферою. Тоді @ApplicationScopedце анотації, що визначають бін.

З специфікацією CDI 1.1: Коли програма в режимі виявлення = анотована, Weld не ідентифікує боби @Singletonта не завантажує це


2

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


Ви мали на увазі "конструктор за замовчуванням"?
Treefish Zhang
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.