W CDI jest pseudozakres @ApplicationScoped
i ( javax.inject
) @Singleton
. Jaka jest różnica między nimi? Poza tym, że @ApplicationScoped
jest proxy, a @Singleton
nie jest.
Czy mogę po prostu zmienić moją @Singleton
fasolę na @ApplicationScoped
? Czy @ApplicationScoped
fasola może mieć dwie (lub więcej) instancje?
@ApplicationScoped
i@Singleton
w sekcji 5.4 (str. 36).Odpowiedzi:
@Singleton
nie jest częścią specyfikacji CDI. Jest częścią EJB ijavax.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.źródło
@Singleton
. Przedstawiono to tylko w jednym przykładzie, bez wyjaśnień. Prawdą jest, że CDI opiera się najavax.inject
, ale ściśle mówiąc nie jest częścią specyfikacji CDI. To powiedziawszy, poprawiłem nieco swoją odpowiedź.w skrócie: możesz nawet mieszać (
@Singleton
i@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:
(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
ale:
... co nadal jest prawdą w moim przypadku.
Singleton EJB vs. Application Scoped Bean
Zamykający
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
źródło
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
@Singleton
jest ratunkiem. PonieważSingleton
jest to pseudozakres i nie jest udostępniany przez proxy jak każdy „normalny” zasięg.źródło
@Singleton
w JSR-299 odnosi się do ziaren sesyjnych Singleton (javax.ejb.Singleton
niejavax.inject.Singleton
), a nie do ziaren zarządzanych przez JSR-299 we wbudowanym zakresie zwanym Singleton.Możesz znaleźć na swoim serwerze
@ApplicationScoped
jeden 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.źródło
Jest jeszcze jedna różnica:
@Singleton
adnotacje nie definiują fasoli, ponieważSingleton
zakres nie jest normalnym zakresem. Następnie@ApplicationScoped
jest bean definiujące adnotacje.Ze specyfikacją CDI 1.1: Gdy aplikacja w trybie wykrywania = z adnotacją, Weld nie identyfikuje ziarna z tym
@Singleton
i nie jest załadowanyźródło
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żywaniajavax.enterprise.context.ApplicationScoped
i to jestJBOSS 6.1 GA Final
implementacjaźródło