Jaka jest różnica między zakresami @ApplicationScoped i @Singleton w CDI?

96

W CDI jest pseudozakres @ApplicationScopedi ( javax.inject) @Singleton. Jaka jest różnica między nimi? Poza tym, że @ApplicationScopedjest proxy, a @Singletonnie jest.

Czy mogę po prostu zmienić moją @Singletonfasolę na @ApplicationScoped? Czy @ApplicationScopedfasola może mieć dwie (lub więcej) instancje?

amorfis
źródło
12
Czy przeczytałeś referencje dotyczące spoin ? Istnieje pewne wyjaśnienie praktycznych różnic między @ApplicationScopedi @Singletonw sekcji 5.4 (str. 36).
brandizzi
1
do którego zakresu Singleton się odnosisz - javax.ejb czy javax.inject?
John Ament,

Odpowiedzi:

30

@Singletonnie jest częścią specyfikacji CDI. Jest częścią EJB i javax.inject(JSR-330). W specyfikacji nie podano, jakie jest jego zachowanie, więc możesz polegać tylko na tym, co jest napisane w dokumentacji Weld.

Bozho
źródło
11
To nieprawda. Istnieje adnotacja javax.inject.Singleton. Jest częścią CDI. Sprawdź tutaj: docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/…
amorfis
5
@amorphis - mam przed sobą specyfikację CDI. Zaimplementowałem nawet części tego, o czym nic nie wspomina @Singleton. Przedstawiono to tylko w jednym przykładzie, bez wyjaśnień. Prawdą jest, że CDI opiera się na javax.inject, ale ściśle mówiąc nie jest częścią specyfikacji CDI. To powiedziawszy, poprawiłem nieco swoją odpowiedź.
Bozho
17

w skrócie: możesz nawet mieszać ( @Singletoni @ApplicationScoped) i ma to sens w niektórych scenariuszach. (i działa zgodnie z oczekiwaniami w moim!)

Oprócz innych odpowiedzi do tej pory chciałbym dodać więcej punktów do wyjaśnienia w rzeczywistych scenariuszach.

Dla mnie to pytanie opracowano z artykułu Jak wymusić wystąpienie komponentu bean o zasięgu aplikacji podczas uruchamiania aplikacji? W pewnej dyskusji stwierdziłem to i jak dotąd nie mogę znaleźć ważnego argumentu przeciwko temu:

W wielu rzeczywistych scenariuszach / konfiguracjach, powiedziałbym, że trudno jest definitywnie powiedzieć - z abstrakcyjnego / modelowego punktu widzenia - czy coś jest (lub zostanie / będzie traktowane jak) EJB lub zarządzana fasola o zasięgu aplikacji.

(dyskusyjne, ale nie rozstrzygające) argumenty (z mojego punktu widzenia) przeciwko temu do tej pory: (@BalusC i wszyscy inni: chciałbym, aby były rozstrzygające, ale jeśli nie, powyższe może być prawdziwe, a mimo to argumenty mogą nadal pomagaj czytelnikowi poznać różnice / zalety / wady / złe / dobre praktyki)

EJB a Managed Bean

BalusC : To jest EJB, a nie zarządzana fasola, co jest całkiem inne. Komponenty EJB działają na zapleczu i zarządzają komponentami typu bean w interfejsie użytkownika. EJB działają również w kontekście transakcyjnym. [...] Właśnie pomyliłeś fasolę korporacyjną z fasolą zarządzaną i właśnie na to zwróciłem uwagę.

ale:

ja : Myślę, że nie masz racji i zawyżasz znaczenie / użycie i wydaje mi się to dyskusyjne.http://en.wikipedia.org/wiki/Enterprise_JavaBeans

Enterprise JavaBeans (EJB) to zarządzane oprogramowanie serwerowe do modułowej budowy oprogramowania korporacyjnego i jeden z kilku interfejsów API języka Java. EJB to składnik oprogramowania po stronie serwera, który hermetyzuje logikę biznesową aplikacji.

Rodzaje fasoli przedsiębiorstwa

Fasola sesji [3], które mogą być „Stateful”, „Stateless” lub „Singleton” [...]

Fasola sterowana wiadomością [...]

... co nadal jest prawdą w moim przypadku.

Singleton EJB vs. Application Scoped Bean

Zamykający

BalusC : Pojedynczy komponent EJB to nie to samo, co komponent bean o zasięgu aplikacji. Pojedynczy EJB jest zablokowany do odczytu / zapisu, a tym samym potencjalnie nieefektywny / nadmiernie skonstruowany dla zadania, które miałeś na myśli. Krótko mówiąc: weź dobrą książkę o Java EE i naucz się używać odpowiedniego narzędzia do pracy. Jeden sposób na pewno nie jest inny. To, że działa, nie oznacza, że ​​jest to właściwe narzędzie. Młot kowalski jest w stanie przykręcić śrubę, ale niekoniecznie jest do tego odpowiednim narzędziem :)

ale:

(Nie widzę tu młota - przepraszam ...) Dobrze jest znać domyślne ustawienia blokowania (nie byłem tego świadomy), ale znowu wydaje się to niepoprawne: Samouczek Oracle Java EE 6 dotyczący zarządzania równoczesnym dostępem w Singleton Session Bean

Podczas tworzenia pojedynczego komponentu bean sesji współbieżny dostęp do metod biznesowych singletona można kontrolować na dwa sposoby: współbieżność zarządzana przez kontener i współbieżność zarządzana przez komponent bean. […]

Chociaż domyślnie singletony używają współbieżności zarządzanej przez kontener, adnotacja @ConcurrencyManagement (CONTAINER) może zostać dodana na poziomie klasy singletona, aby jawnie ustawić typ zarządzania współbieżnością

Andreas Dietrich
źródło
Spawanie nie jest zabawne mieszaniem: Wyjątek podczas ładowania aplikacji: Błąd definicji CDI: WELD-000046: W [EnhancedAnnotatedTypeImpl] public ApplicationScoped Singleton MyClass można określić najwyżej jeden zakres. Korzystanie z javax.inject.Singleton.
sgflt
12

Zwykle, gdy chcesz mieć tylko jedną instancję jakiegoś obiektu, prawdopodobnie powinieneś użyć @ApplicationScoped adnotacji - taki obiekt jest proxy, a zatem może nawet zostać poprawnie serializowany po wyjęciu z pudełka.

Z drugiej strony jest też wiele przypadków, w których potrzebujesz tylko jednej instancji klasy, ale takiej klasy nie można proxy (np. Ponieważ jest ostateczna) - wtedy @Singletonjest ratunkiem. Ponieważ Singletonjest to pseudozakres i nie jest udostępniany przez proxy jak każdy „normalny” zasięg.

G. Demecki
źródło
Odrzucam to, ponieważ jest to bardzo niejasne. Piszę w Java EE od pięciu lat, korzystam z samouczków i czytam książki, ale nie mam jasnego pojęcia, co masz na myśli, gdy mówisz „taki obiekt jest proxy”, „można go nawet poprawnie zserializować” i „pseudo- zakres". Chciałbym wiedzieć, co przez to rozumie, ponieważ brzmi to tak, jakbyś wiedział, o czym mówisz, ale jak jest napisane, nie wyobrażam sobie, że twoja odpowiedź pomoże większości programistów Java EE.
DavidS
2
To powiedziawszy, wiem, że EJB są proxy. Moje zamieszanie częściowo dotyczy rozróżnienia, jakie robisz dla Singletonów.
DavidS
9

@Singletonw JSR-299 odnosi się do ziaren sesyjnych Singleton ( javax.ejb.Singletonnie javax.inject.Singleton), a nie do ziaren zarządzanych przez JSR-299 we wbudowanym zakresie zwanym Singleton.

Możesz znaleźć na swoim serwerze @ApplicationScopedjeden na EAR lub jeden na WAR / EJB-JAR, ponieważ nie jest to jasne w specyfikacji, ale zdecydowanie nie powinieneś oczekiwać, że będzie to jeden na JVM.

covener
źródło
7

Jest jeszcze jedna różnica: @Singletonadnotacje nie definiują fasoli, ponieważ Singletonzakres nie jest normalnym zakresem. Następnie @ApplicationScopedjest bean definiujące adnotacje.

Ze specyfikacją CDI 1.1: Gdy aplikacja w trybie wykrywania = z adnotacją, Weld nie identyfikuje ziarna z tym @Singletoni nie jest załadowany

wigor
źródło
2

Jedna z głównych różnic, które możesz napisać swoją klasę z domyślnym konstruktorem, ma prywatny modyfikator dostępu podczas używania javax.inject.Singleton, ale twoja klasa powinna mieć domyślny konstruktor z co najmniej domyślnym modyfikatorem dostępu podczas używania javax.enterprise.context.ApplicationScopedi to jest JBOSS 6.1 GA Finalimplementacja

user1017344
źródło
Czy chodziło Ci o „domyślny konstruktor”?
Treefish Zhang