Di CDI ada pseudo-scope @ApplicationScoped
dan ( javax.inject
) @Singleton
. Apa perbedaan di antara keduanya? Selain fakta yang @ApplicationScoped
diproksikan, dan @Singleton
tidak.
Bisakah saya mengubah @Singleton
kacang saya menjadi @ApplicationScoped
? Bisakah @ApplicationScoped
kacang memiliki dua (atau lebih) contoh?
@ApplicationScoped
dan@Singleton
pada bagian 5.4 (hlm. 36).Jawaban:
@Singleton
bukan bagian dari spesifikasi CDI. Ini adalah bagian dari EJB danjavax.inject
(JSR-330). Tidak disebutkan dalam spesifikasi apa perilakunya, jadi Anda hanya dapat mengandalkan apa yang tertulis dalam dokumentasi Weld.sumber
@Singleton
. Ini ditunjukkan hanya dalam satu contoh, tanpa klarifikasi. Memang benar bahwa CDI bergantungjavax.inject
, tetapi secara tegas itu bukan bagian dari spesifikasi CDI. Meski begitu, saya mengoreksi jawaban saya sedikit.singkatnya: Anda bahkan dapat mencampurnya (
@Singleton
dan@ApplicationScoped
) dan itu masuk akal dalam beberapa skenario. (dan bekerja seperti yang diharapkan di milik saya!)Selain jawaban lain sejauh ini, saya ingin menambahkan beberapa poin lagi untuk klarifikasi dalam skenario dunia nyata.
Bagi saya, pertanyaan ini dikembangkan dari Bagaimana cara memaksa kacang bercakupan aplikasi untuk dipakai saat startup aplikasi? Dalam beberapa diskusi di sana saya menyatakan ini dan sejauh ini tidak dapat menemukan argumen yang valid untuk menentangnya:
Argumen (bisa diperdebatkan tetapi tidak konklusif) (dari sudut pandang saya) yang menentangnya sejauh ini: (@BalusC dan lainnya: Saya ingin melihat mereka menjadi konklusif, tetapi jika tidak, hal di atas mungkin benar dan meskipun demikian argumennya mungkin tetap membantu pembaca untuk mendapatkan perbedaan / kelebihan / kekurangan / buruk / praktik yang baik)
EJB vs. Kacang Terkelola
tapi:
... yang masih berlaku dalam kasus saya.
Singleton EJB vs. Application Scoped Bean
Mengunci
tapi:
(Saya tidak bisa melihat palu godam di sini - maaf ...) Ada baiknya mengetahui default penguncian (saya tidak menyadarinya), tetapi ini tampaknya salah lagi: Tutorial Oracle Java EE 6 tentang Mengelola Akses Bersamaan di a Singleton Session Bean
sumber
Biasanya ketika Anda ingin memiliki hanya satu contoh dari beberapa objek, Anda mungkin harus menggunakan
@ApplicationScoped
anotasi - objek seperti itu diproksikan dan dengan demikian bahkan dapat diserialkan dengan benar di luar kotak.Di sisi lain, ada juga banyak kasus, di mana Anda hanya menginginkan satu instance kelas, tetapi kelas tersebut tidak dapat diproksikan (misalnya karena sudah final) - maka itu
@Singleton
adalah penyelamatan. KarenaSingleton
merupakan lingkup semu dan tidak sedang diproksikan seperti lingkup "normal" lainnya.sumber
@Singleton
di JSR-299 mengacu pada kacang sesi Singleton (javax.ejb.Singleton
, bukanjavax.inject.Singleton
), bukan kacang yang dikelola JSR-299 dalam lingkup built-in yang disebut Singleton.Anda mungkin menemukan di server Anda bahwa
@ApplicationScoped
satu-per EAR atau satu-per WAR / EJB-JAR karena tidak jelas dalam spesifikasinya, tetapi Anda seharusnya tidak mengharapkannya menjadi satu per JVM.sumber
Ada satu perbedaan lagi:
@Singleton
bukan anotasi yang mendefinisikan kacang, karenaSingleton
cakupannya bukan cakupan normal. Kemudian@ApplicationScoped
adalah penjelasan yang mendefinisikan kacang.Dengan spesifikasi CDI 1.1: Ketika aplikasi dalam mode penemuan = dianotasi, Weld tidak mengidentifikasi kacang dengan
@Singleton
dan tidak memuat inisumber
Salah satu perbedaan utama bahwa Anda dapat menulis kelas Anda dengan konstruktor default memiliki pengubah akses pribadi saat menggunakan
javax.inject.Singleton
, tetapi kelas Anda harus memiliki konstruktor default dengan setidaknya pengubah akses default saat menggunakanjavax.enterprise.context.ApplicationScoped
dan ini adalahJBOSS 6.1 GA Final
implementasisumber