Saya perhatikan bahwa ada beberapa lingkup kacang yang berbeda seperti:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Apa tujuan masing-masing? Bagaimana cara memilih ruang lingkup yang sesuai untuk kacang saya?
jsf
jsf-2
scope
managed-bean
Valter Silva
sumber
sumber
Jawaban:
pengantar
Ini mewakili ruang lingkup (masa hidup) kacang. Ini lebih mudah untuk dipahami jika Anda terbiasa dengan "di bawah penutup" bekerja dari aplikasi web servlet dasar: Bagaimana cara kerja servlets? Instansiasi, sesi, variabel bersama, dan multithreading .
@Request/View/Flow/Session/ApplicationScoped
Sebuah
@RequestScoped
kacang hidup selama siklus permintaan-respon tunggal HTTP (catatan bahwa Ajax permintaan dianggap sebagai satu permintaan HTTP juga). Sebuah@ViewScoped
kacang hidup selama Anda berinteraksi dengan pandangan JSF yang sama oleh postbacks yang metode tindakan panggilan kembalinull
/void
tanpa navigasi / redirect. Sebuah@FlowScoped
kacang hidup selama Anda menavigasi melalui koleksi tertentu dari pandangan terdaftar di file konfigurasi aliran. Sebuah@SessionScoped
kacang hidup selama sesi HTTP didirikan. Sebuah@ApplicationScoped
kacang hidup selama berjalan aplikasi web. Perhatikan bahwa CDI@Model
pada dasarnya adalah stereotip untuk@Named @RequestScoped
, jadi aturan yang sama berlaku.Cakupan mana yang dipilih hanya bergantung pada data (negara bagian) yang dipegang dan diwakili kacang. Gunakan
@RequestScoped
untuk bentuk / presentasi sederhana dan non-ajax. Gunakan@ViewScoped
untuk tampilan dinamis yang kaya ajax (validasi ajax, rendering, dialog, dll). Gunakan@FlowScoped
untuk pola "penyihir" ("kuesioner") untuk mengumpulkan data input yang tersebar di beberapa halaman. Gunakan@SessionScoped
untuk data spesifik klien, seperti pengguna yang masuk dan preferensi pengguna (bahasa, dll.) Gunakan@ApplicationScoped
untuk aplikasi luas data / konstanta, seperti daftar dropdown yang sama untuk semua orang, atau kacang yang dikelola tanpa variabel instan dan hanya memiliki metode.Menyalahgunakan
@ApplicationScoped
kacang untuk data cakupan / sesi / tampilan / permintaan akan membuatnya untuk dibagikan di antara semua pengguna, sehingga orang lain dapat melihat data masing-masing yang jelas-jelas salah. Menyalahgunakan@SessionScoped
kacang untuk melihat / meminta data cakupan akan membuatnya untuk dibagikan di antara semua tab / jendela dalam satu sesi browser, sehingga pengguna akhir dapat mengalami ketidakkonsistenan saat berinteraksi dengan setiap tampilan setelah beralih di antara tab yang buruk untuk pengalaman pengguna. Menyalahgunakan@RequestScoped
kacang untuk melihat data cakupan akan membuat tampilan data cakupan untuk diinisialisasi ulang ke default pada setiap postback tunggal (ajax), menyebabkan kemungkinan bentuk tidak berfungsi ( lihat juga poin 4 dan 5 di sini ). Menyalahgunakan@ViewScoped
kacang untuk permintaan, sesi atau data cakupan aplikasi, dan menyalahgunakan a@SessionScoped
kacang untuk data cakupan aplikasi tidak mempengaruhi klien, tetapi tidak perlu menempati memori server dan jelas tidak efisien.Perhatikan bahwa ruang lingkup sebaiknya tidak dipilih berdasarkan implikasi kinerja, kecuali jika Anda benar - benar memiliki jejak memori yang rendah dan ingin menjadi benar-benar tanpa kewarganegaraan; Anda harus menggunakan
@RequestScoped
kacang dan biola secara eksklusif dengan parameter permintaan untuk mempertahankan status klien. Perhatikan juga bahwa ketika Anda memiliki halaman JSF tunggal dengan data cakupan yang berbeda, maka sangat sah untuk menempatkannya di kacang latar terpisah dalam ruang lingkup yang cocok dengan ruang lingkup data. Kacang hanya dapat mengakses satu sama lain@ManagedProperty
dalam kasus kacang dikelola JSF atau@Inject
dalam kasus kacang dikelola CDI.Lihat juga:
@CustomScoped/NoneScoped/Dependent
Ini tidak disebutkan dalam pertanyaan Anda, tetapi (warisan) JSF juga mendukung
@CustomScoped
dan@NoneScoped
, yang jarang digunakan di dunia nyata. Mereka@CustomScoped
harus merujukMap<K, Bean>
implementasi kustom dalam beberapa lingkup yang lebih luas yang telah menimpaMap#put()
dan / atauMap#get()
untuk memiliki kontrol yang lebih baik atas pembuatan dan / atau penghancuran kacang.JSF
@NoneScoped
dan CDI@Dependent
pada dasarnya hidup selama EL-evaluasi tunggal pada kacang. Bayangkan formulir login dengan dua bidang input yang merujuk ke properti kacang dan tombol perintah yang merujuk pada tindakan kacang, sehingga dengan total tiga ekspresi EL, maka secara efektif tiga instance akan dibuat. Satu dengan set nama pengguna, satu dengan set kata sandi dan satu di mana tindakan dipanggil. Anda biasanya ingin menggunakan ruang lingkup ini hanya pada kacang yang harus hidup selama kacang disuntikkan. Jadi jika a@NoneScoped
atau@Dependent
disuntikkan dalam@SessionScoped
, maka itu akan hidup selama@SessionScoped
kacang.Lihat juga:
Lingkup flash
Seperti yang terakhir, JSF juga mendukung lingkup flash. Itu didukung oleh cookie hidup pendek yang terkait dengan entri data dalam cakupan sesi. Sebelum pengalihan, cookie akan ditetapkan pada respons HTTP dengan nilai yang secara unik terkait dengan entri data dalam cakupan sesi. Setelah pengalihan, keberadaan cookie lingkup flash akan diperiksa dan entri data yang terkait dengan cookie akan dihapus dari cakupan sesi dan dimasukkan ke dalam lingkup permintaan permintaan yang diarahkan. Akhirnya cookie akan dihapus dari respons HTTP. Dengan cara ini permintaan yang dialihkan memiliki akses untuk meminta data cakupan yang telah disiapkan dalam permintaan awal.
Ini sebenarnya tidak tersedia sebagai ruang lingkup kacang dikelola, yaitu tidak ada hal seperti itu
@FlashScoped
. Cakupan flash hanya tersedia sebagai peta melaluiExternalContext#getFlash()
kacang yang dikelola dan#{flash}
EL.Lihat juga:
sumber
@FlowScoped
(tidak perlu secara manual memulai / menghentikannya).ViewAccesscoped
danWindowScoped
ViewScoped
kacang di MyFaces 2.2. Saat ini saya menghadapi masalah denganViewScoped
kacang dan Ajax, yang telah saya posting di sini . Di MyFaces JIRA, ada juga diskusi tentang topik ini.@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped
mengapa cakupan yang Anda gambarkan berbeda?Karena JSF 2.3 semua cakupan bean yang didefinisikan dalam paket
javax.faces.bean
paket telah ditinggalkan untuk menyelaraskan cakupan dengan CDI. Selain itu mereka hanya berlaku jika kacang Anda menggunakan@ManagedBean
anotasi. Jika Anda menggunakan versi JSF di bawah 2.3, lihat jawaban lawas di bagian akhir.Dari JSF 2.3 berikut ini adalah cakupan yang dapat digunakan pada JSF Backing Beans:
1
@javax.enterprise.context.ApplicationScoped
.: Cakupan aplikasi berlanjut selama seluruh durasi aplikasi web. Cakupan itu dibagi di antara semua permintaan dan semua sesi. Ini berguna ketika Anda memiliki data untuk seluruh aplikasi.2
@javax.enterprise.context.SessionScoped
.: Cakupan sesi berlanjut dari saat sesi ditetapkan hingga sesi dihentikan. Konteks sesi dibagi antara semua permintaan yang terjadi dalam sesi HTTP yang sama. Ini berguna ketika Anda tidak ingin menyimpan data untuk klien tertentu untuk sesi tertentu.3
@javax.enterprise.context.ConversationScoped
.: Ruang lingkup percakapan tetap sebagai log seperti kacang hidup. Ruang lingkup menyediakan 2 metode:Conversation.begin()
danConversation.end()
. Metode-metode ini harus disebut secara eksplisit, baik untuk memulai atau mengakhiri kehidupan kacang.4
@javax.enterprise.context.RequestScoped
.: Ruang lingkup permintaan berumur pendek. Itu dimulai ketika permintaan HTTP diajukan dan berakhir setelah respons dikirim kembali ke klien. Jika Anda menempatkan kacang yang dikelola ke dalam ruang lingkup permintaan, instance baru dibuat dengan setiap permintaan. Sebaiknya pertimbangkan cakupan permintaan jika Anda khawatir tentang biaya penyimpanan lingkup sesi.5
@javax.faces.flow.FlowScoped
.: Lingkup Flow tetap ada selama Flow hidup. Alur dapat didefinisikan sebagai kumpulan halaman (atau tampilan) yang terkandung yang mendefinisikan unit kerja. Flow scoped telah aktif selama pengguna menavigasi dalam Flow.6
@javax.faces.view.ViewScoped
.: Kacang dalam lingkup tampilan tetap ada sementara halaman JSF yang sama ditampilkan ulang. Segera setelah pengguna menavigasi ke halaman yang berbeda, kacang keluar dari ruang lingkup.Jawaban warisan berikut berlaku versi JSF sebelum 2.3
Sumber: Core Java Server Faces 3rd Edition oleh David Geary & Cay Horstmann [Halaman no. 51 - 54]
sumber
invalidate()
metode, atau metode tidak valid?FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
dipanggil dalam "kacang logout" Anda adalah apa yang ia maksudkan.