Saya belajar Spring Framework yang sedang digunakan dalam proyek saya. Saya menemukan entri ContextLoaderListener di file web.xml saya . Tetapi tidak dapat mengetahui bagaimana tepatnya hal itu membantu pengembang?
Dalam dokumentasi resmi ContextLoaderListener dikatakan mengatakan untuk memulai WebApplicationContext . Mengenai WebApplicationContext, JavaDocs mengatakan:
Antarmuka untuk memberikan konfigurasi untuk aplikasi web.
Tetapi saya tidak dapat memahami apa yang saya capai dengan ContextLoaderListener yang secara internal menginisialisasi WebApplicationContext ?
Sesuai pemahaman saya , ContextLoaderListener membaca file konfigurasi Spring (dengan nilai yang diberikan terhadap contextConfigLocation di web.xml ), mem- parsingnya dan memuat kacang tunggal yang didefinisikan dalam file konfigurasi tersebut. Demikian pula ketika kita ingin memuat kacang prototipe , kita akan menggunakan konteks aplikasi web yang sama untuk memuatnya. Jadi kami menginisialisasi aplikasi web dengan ContextLoaderListener sehingga kami membaca / parse / memvalidasi file konfigurasi terlebih dahulu dan setiap kali kami ingin menyuntikkan dependensi, kami dapat langsung melakukannya tanpa penundaan. Apakah pemahaman ini benar?
sumber
Jawaban:
Pemahaman Anda benar. Di
ApplicationContext
sinilah kacang Spring Anda hidup. TujuannyaContextLoaderListener
adalah dua kali lipat:untuk mengikat siklus hidup
ApplicationContext
ke siklus hidupServletContext
danuntuk mengotomatiskan pembuatan
ApplicationContext
, jadi Anda tidak perlu menulis kode eksplisit untuk membuatnya - ini adalah fungsi yang praktis.Hal lain yang nyaman tentang itu
ContextLoaderListener
adalah bahwa ia menciptakanWebApplicationContext
danWebApplicationContext
menyediakan akses ke kacangServletContext
melaluiServletContextAware
dangetServletContext
metode.sumber
WebApplicationContext
. Kalau tidak, harus dibuat secara manual.ContextLoaderListener
menerapkan metode penghancuran untuk menghancurkan semua kacang ketika wadah web dimatikan?contextDestroyed
dipanggil. Lihat dokumentasi API.web.xml
. Di file xml saya ada dua pendengarContextLoaderListener
danDispatcherServlet
. Jadi saya kira tidak perlu keduanya, apakah aman untuk menghapusContextLoaderListener
mengapa saya bertanya karena aplikasi hidup sejak 7-8 bulan. web.xml ada di sini untuk referensi Anda.ContextLoaderListener
adalah opsional . Hanya untuk membuat titik di sini: Anda dapat boot up aplikasi musim semi tanpa pernah mengkonfigurasiContextLoaderListener
, hanya dasar minimumweb.xml
denganDispatcherServlet
.Ini akan terlihat seperti apa:
web.xml
Buat file yang dipanggil
dispatcher-servlet.xml
dan simpan di bawahWEB-INF
. Karena kami sebutkanindex.jsp
dalam daftar selamat datang, tambahkan file ini di bawahWEB-INF
.dispatcher-servlet.xml
Di
dispatcher-servlet.xml
tentukan kacang Anda:sumber
Untuk aplikasi Musim Semi yang sederhana, Anda tidak perlu mendefinisikan
ContextLoaderListener
diweb.xml
; Anda bisa meletakkan semua file konfigurasi Spring Anda di<servlet>
:Untuk aplikasi Pegas yang lebih kompleks, di mana Anda memiliki banyak
DispatcherServlet
definisi, Anda dapat memiliki file konfigurasi Pegas umum yang digunakan bersama oleh semua yangDispatcherServlet
didefinisikan dalamContextLoaderListener
:Hanya perlu diingat,
ContextLoaderListener
melakukan pekerjaan inisialisasi aktual untuk root konteks aplikasi .Saya menemukan artikel ini banyak membantu: Spring MVC - Konteks Aplikasi vs Konteks Aplikasi Web
sumber
Blog, " Purpose of ContextLoaderListener - Spring MVC " memberikan penjelasan yang sangat bagus.
Menurutnya, Konteks Aplikasi adalah hierarki dan karenanya konteks DispatcherSerlvet menjadi anak konteks ContextLoaderListener. Karena itu, teknologi yang digunakan dalam lapisan pengontrol (Struts atau Spring MVC) dapat terlepas dari konteks akar yang dibuat ContextLoaderListener.
sumber
Ketika Anda ingin meletakkan file Servlet Anda di lokasi kustom Anda atau dengan nama kustom, daripada konvensi penamaan default
[servletname]-servlet.xml
dan jalur di bawahWeb-INF/
, maka Anda dapat menggunakanContextLoaderListener
.sumber
ContextLoaderListner adalah pendengar Servlet yang memuat semua file konfigurasi yang berbeda (konfigurasi lapisan layanan, konfigurasi lapisan persistensi, dll.) Ke dalam konteks aplikasi pegas tunggal.
Ini membantu untuk membagi konfigurasi pegas di beberapa file XML.
Setelah file konteks dimuat, Spring membuat objek WebApplicationContext berdasarkan definisi bean dan menyimpannya dalam ServletContext aplikasi web Anda.
sumber
Pendengar Bootstrap ini untuk memulai dan mematikan root Spring WebApplicationContext . Karena aplikasi web dapat memiliki beberapa servlet dispatcher dan masing-masing memiliki konteks aplikasi sendiri yang mengandung pengontrol, view resolver, pemetaan handler dll. Tetapi Anda mungkin ingin memiliki kacang layanan, kacang DAO dalam konteks aplikasi root dan ingin digunakan dalam semua konteks aplikasi anak ( konteks aplikasi yang dibuat oleh servlet operator).
Penggunaan kedua pendengar ini adalah saat Anda ingin menggunakan keamanan pegas.
sumber
Konteks root dan anak Sebelum membaca lebih lanjut, harap dipahami bahwa -
Musim semi dapat memiliki banyak konteks sekaligus. Salah satunya adalah konteks root, dan semua konteks lainnya adalah konteks anak.
Semua konteks anak dapat mengakses kacang yang didefinisikan dalam konteks root; tetapi kebalikannya tidak benar. Konteks root tidak dapat mengakses kacang konteks anak.
ApplicationContext:
applicationContext.xml adalah konfigurasi konteks root untuk setiap aplikasi web. Pegas memuat file applicationContext.xml dan membuat ApplicationContext untuk seluruh aplikasi. Hanya akan ada satu konteks aplikasi per aplikasi web. Jika Anda tidak secara eksplisit mendeklarasikan nama file konfigurasi konteks di web.xml menggunakan param contextConfigLocation, Spring akan mencari applicationContext.xml di bawah folder WEB-INF dan melempar FileNotFoundException jika tidak dapat menemukan file ini.
ContextLoaderListener Melakukan pekerjaan inisialisasi aktual untuk konteks aplikasi root. Membaca konteks-param "contextConfigLocation" dan meneruskan nilainya ke instance konteks, mem-parsingnya ke beberapa path file yang berpotensi yang dapat dipisahkan oleh sejumlah koma dan spasi, misalnya "WEB-INF / applicationContext1.xml, WEB-INF / applicationContext2.xml ”. ContextLoaderListener adalah opsional. Hanya untuk menjelaskan di sini: Anda dapat mem-boot aplikasi Musim Semi tanpa pernah mengkonfigurasi ContextLoaderListener, hanya web.xml minimum dasar dengan DispatcherServlet.
DispatcherServlet DispatcherServlet pada dasarnya adalah Servlet (ini meluas HttpServlet) yang tujuan utamanya adalah untuk menangani permintaan web masuk yang cocok dengan pola URL yang dikonfigurasi. Dibutuhkan URI yang masuk dan menemukan kombinasi yang tepat dari pengontrol dan tampilan. Jadi itu adalah pengontrol depan.
Ketika Anda menentukan DispatcherServlet dalam konfigurasi pegas, Anda memberikan file XML dengan entri kelas controller, melihat pemetaan dll menggunakan atribut contextConfigLocation.
WebApplicationContext Terlepas dari ApplicationContext, ada beberapa WebApplicationContext dalam satu aplikasi web. Dengan kata sederhana, setiap DispatcherServlet terkait dengan WebApplicationContext tunggal. file xxx-servlet.xml khusus untuk DispatcherServlet dan aplikasi web dapat memiliki lebih dari satu DispatcherServlet yang dikonfigurasi untuk menangani permintaan. Dalam skenario seperti itu, setiap DispatcherServlet akan memiliki xxx-servlet.xml yang terpisah dikonfigurasi. Tetapi, applicationContext.xml akan umum untuk semua file konfigurasi servlet. Pegas akan secara default memuat file bernama "xxx-servlet.xml" dari folder webapp WEB-INF Anda di mana xxx adalah nama servlet di web.xml. Jika Anda ingin mengubah nama nama file itu atau mengubah lokasi, tambahkan initi-param dengan contextConfigLocation sebagai nama param.
Perbandingan dan hubungan di antara mereka:
ContextLoaderListener vs DispatcherServlet
ContextLoaderListener membuat konteks aplikasi root. Entri DispatcherServlet membuat konteks aplikasi satu anak per entri servlet. Konteks anak dapat mengakses kacang yang didefinisikan dalam konteks root. Kacang dalam konteks root tidak dapat mengakses kacang dalam konteks anak (langsung). Semua konteks ditambahkan ke ServletContext. Anda dapat mengakses konteks root menggunakan kelas WebApplicationContextUtils.
Setelah membaca dokumentasi Spring, berikut ini adalah pengertiannya:
a) Aplikasi-Konteks adalah hierarkis dan begitu juga WebApplicationContexts. Lihat dokumentasi di sini.
b) ContextLoaderListener membuat root web-application-context untuk aplikasi web dan meletakkannya di ServletContext. Konteks ini dapat digunakan untuk memuat dan membongkar biji yang dikelola pegas terlepas dari teknologi apa yang digunakan dalam lapisan pengontrol (Struts atau Spring MVC).
c) DispatcherServlet membuat WebApplicationContext sendiri dan handler / controllers / view-resolvers dikelola oleh konteks ini.
d) Ketika ContextLoaderListener digunakan bersama-sama dengan DispatcherServlet, konteks web-aplikasi root dibuat terlebih dahulu seperti yang dikatakan sebelumnya dan konteks anak-anak juga dibuat oleh DispatcherSerlvet dan dilampirkan ke konteks aplikasi root. Lihat dokumentasi di sini.
Ketika kami bekerja dengan Spring MVC dan juga menggunakan Spring di lapisan layanan, kami menyediakan dua konteks aplikasi. Yang pertama dikonfigurasi menggunakan ContextLoaderListener dan yang lainnya dengan DispatcherServlet
Secara umum, Anda akan mendefinisikan semua kacang terkait MVC (controller dan tampilan dll) dalam konteks DispatcherServlet, dan semua kacang lintas-potong seperti keamanan, transaksi, layanan dll pada konteks akar oleh ContextLoaderListener.
Lihat ini untuk detail lebih lanjut: https://siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html
sumber
Pada dasarnya Anda dapat mengisolasi konteks aplikasi root dan konteks aplikasi web menggunakan ContextLoaderListner.
File config yang dipetakan dengan param konteks akan berperilaku sebagai konfigurasi konteks aplikasi root. Dan file konfigurasi yang dipetakan dengan servlet dispatcher akan berperilaku seperti konteks aplikasi web.
Dalam aplikasi web apa pun kami mungkin memiliki beberapa servlet operator, jadi beberapa konteks aplikasi web.
Tetapi dalam aplikasi web apa pun kita mungkin hanya memiliki satu konteks aplikasi root yang dibagikan dengan semua konteks aplikasi web.
Kita harus mendefinisikan layanan umum kita, entitas, aspek dll dalam konteks aplikasi root. Dan pengendali, pencegat dll dalam konteks aplikasi web yang relevan.
Sampel web.xml adalah
Di sini config class example.config.AppConfig dapat digunakan untuk mengkonfigurasi layanan, entitas, aspek dll dalam konteks aplikasi root yang akan dibagikan dengan semua konteks aplikasi web lainnya (misalnya di sini kami memiliki dua kelas konfigurasi konteks aplikasi web, RestConfig dan WebConfig)
PS: Di sini ContextLoaderListener sepenuhnya opsional. Jika kami tidak akan menyebut ContextLoaderListener di web.xml di sini, AppConfig tidak akan berfungsi. Dalam hal ini kita perlu mengkonfigurasi semua layanan dan entitas kita di WebConfig dan Rest Config.
sumber
Ini akan memberi Anda point of hook untuk menaruh beberapa kode yang Anda ingin dieksekusi pada waktu penyebaran aplikasi web
sumber
Kelas pendengar - Mendengarkan acara (Misalnya .. Server startup / shutdown)
ContextLoaderListener -
File konfigurasi dapat disediakan seperti ini di web.xml
sumber
Dalam konteks kerangka pegas, tujuan ContextLoaderListener adalah untuk memuat kacang lainnya di aplikasi Anda seperti komponen tingkat menengah dan data tingkat yang mendorong bagian belakang aplikasi.
sumber
Pemahaman Anda benar. Saya ingin tahu mengapa Anda tidak melihat kelebihan apa pun di ContextLoaderListener. Misalnya, Anda perlu membangun pabrik sesi (untuk mengelola database). Operasi ini bisa memakan waktu, jadi lebih baik melakukannya saat startup. Tentu saja Anda bisa melakukannya dengan init servlets atau yang lainnya, tetapi keuntungan dari pendekatan Spring adalah Anda membuat konfigurasi tanpa menulis kode.
sumber
Jika kita menulis web.xml tanpa ContextLoaderListener maka kita tidak dapat memberikan informasi menggunakan customAuthenticationProvider dalam keamanan musim semi. Karena DispatcherServelet adalah konteks turunan dari ContextLoaderListener, customAuthenticationProvider adalah bagian dari parentContext yaitu ContextLoaderListener. Jadi Konteks induk tidak dapat memiliki dependensi konteks anak. Maka itu adalah praktik terbaik untuk menulis spring-context.xml dalam contextparam daripada menulisnya di initparam.
sumber
Saya percaya penggunaan sebenarnya datang ketika Anda ingin memiliki lebih dari satu file konfigurasi atau Anda memiliki file xyz.xml alih-alih applicationcontext.xml untuk misalnya
<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>
Pendekatan lain untuk ContextLoaderListener menggunakan ContextLoaderServlet seperti di bawah ini
<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
sumber