1. Latar belakang
Baru-baru ini, karena masalah dengan pemindaian paket proyek, dalam proses menyelesaikan masalah, saya secara tidak sengaja menemukan bahwa Spring dan SpringMVC memiliki hubungan wadah orangtua-anak, dan justru karena inilah masalah pemindaian paket sering terjadi. Di sini kami menganalisis dan memahami hubungan wadah orangtua-anak antara Spring dan SpringMVC dan memberikan cara pemindaian paket yang disarankan secara resmi di file konfigurasi Spring dan SpringMVC.
2. Pemahaman konsep dan pengetahuan meletakkan fondasi
Dalam konsep inti kerangka kerja keseluruhan musim semi, wadah adalah ide inti, yang digunakan untuk mengelola seluruh siklus hidup kacang. Dalam sebuah proyek, tidak ada hanya satu kontainer. Musim semi dapat mencakup beberapa wadah, dan wadah memiliki tingkat atas dan bawah. Skenario yang paling umum saat ini adalah memperkenalkan dua kerangka kerja Spring dan SpringMVC dalam sebuah proyek. Maka itu sebenarnya dua wadah. Spring adalah wadah induk dan SpringMVC adalah wadah anaknya. Kacang yang terdaftar dalam wadah induk musim semi terlihat oleh wadah SpringMVC, sedangkan kacang yang terdaftar dalam wadah SpringMVC tidak terlihat oleh wadah induk musim semi, yaitu, wadah anak dapat melihat kacang terdaftar dalam wadah induk, jika tidak ia tidak akan berfungsi.
Kita dapat menggunakan konfigurasi anotasi terpadu sebagai berikut untuk mendaftarkan batch kacang, tanpa mengkonfigurasi setiap kacang menggunakan XML secara terpisah.
<konteks: komponen-scan-package = "com.hafiz.www" />
Dari manual referensi yang disediakan oleh Spring, kita tahu bahwa fungsi konfigurasi ini adalah untuk memindai semua kelas di bawah paket paket dasar yang dikonfigurasi yang menggunakan anotasi @Component, dan secara otomatis mendaftarkannya ke dalam wadah. Pada saat yang sama, mereka juga memindai tiga anotasi @Controller, @Service, dan @respository karena mereka diwarisi dari @Component.
Dalam proyek, kita sering melihat konfigurasi berikut. Bahkan, dengan konfigurasi di atas, ini dapat dihilangkan, karena konfigurasi di atas akan mengaktifkan konfigurasi berikut secara default. Konfigurasi berikut akan mendeklarasikan anotasi seperti @Required, @Autowired, @PostConstruct, @PersistenceContext, @resource, @predestroy, dll. Secara default.
<Konteks: Anotasi-Konfigurasi/>
Selain itu, ada konfigurasi lain yang terkait dengan SpringMVC. Setelah verifikasi, ini harus dikonfigurasi untuk SpringMVC karena menyatakan @RequestMapping, @RequestBody, @ResponseBody, dll. Selain itu, konfigurasi ini memuat banyak metode pengikatan parameter secara default, seperti parser konversi JSON.
<MVC: Anotasi-Didorong />
Versi konfigurasi kalimat di atas sebelum Spring 3.1 setara dengan metode konfigurasi berikut
<!-Mengkonfigurasi annotation controller mapper, digunakan di springmvc untuk memetakan URL permintaan permintaan ke pengontrol tertentu-> <bean/> <!-Mengkonfigurasi annotation controller mapper, digunakan dalam springmvc untuk memetakan permintaan spesifik ke metode tertentu-> <bean/>
Versi setelah spring3.1 setara dengan metode konfigurasi berikut
<!-Mengkonfigurasi annotation controller mapper, digunakan di springmvc untuk memetakan URL permintaan permintaan ke pengontrol tertentu-> <bean/> <!-Mengkonfigurasi annotation controller mapper, digunakan dalam springmvc untuk memetakan permintaan spesifik ke metode tertentu-> <bean/>
3. Analisis Skenario Khusus
Mari kita lihat lebih dekat penyebab konflik kontainer antara Spring dan SpringMVC?
Kami memiliki dua kontainer, Spring dan SpringMVC, dan file konfigurasinya masing-masing adalah ApplicationContext.xml dan ApplicationContext-Mvc.xml.
1. <Konteks: komponen-scan-package = "com.hafiz.www" /> dikonfigurasi dalam ApplicationContext.xml untuk bertanggung jawab untuk memindai dan mendaftarkan semua kacang yang perlu didaftarkan.
2. Konfigurasikan <MVC: Annotation-Driven /> di ApplicationContext-Mvc.xml untuk bertanggung jawab atas penggunaan anotasi terkait SpringMVC.
3. Saat memulai proyek, kami menemukan bahwa SpringMVC tidak dapat melompat. Kami mengatur tingkat pencetakan log log untuk men -debug untuk debugging. Kami menemukan bahwa permintaan dalam wadah SpringMVC tampaknya tidak dipetakan ke pengontrol tertentu.
4. Konfigurasikan <konteks: komponen-scan-package = "com.hafiz.www" /> di ApplicationContext-Mvc.xml. Setelah restart, verifikasi berhasil dan lompatan SpringMVC valid.
Mari kita periksa alasan spesifik, lihat kode sumber, dan mulai dari DispatcherServlet SpringMVC untuk mencari ke bawah. Kami menemukan bahwa ketika SpringMVC diinisialisasi, kami akan mencari semua kacang dalam wadah SpringMVC yang menggunakan anotasi @Controller untuk menentukan apakah itu penangan. Konfigurasi dua langkah 1 dan 2 membuat wadah SpringMVC saat ini tidak mendaftarkan kacang dengan anotasi @Controller, tetapi semua kacang dengan anotasi @Controller terdaftar dalam wadah induk musim semi, sehingga SpringMVC tidak dapat menemukan prosesor dan tidak dapat melompat. Kode sumber inti adalah sebagai berikut:
void inithandlermethods () {if (logger.isdebugeNabled ()) {if (LOGGER.DEBUG ("Logger (" mencari pemetaan aplikasi dalam konteks aplikasi dalam konteks aplikasi dalam konteks: " + getApplicationContext (); } String [] beanNames = (this.detecthandlermethodsinancestorcontexts? Beanfactoryutils.beannamesfortypeincledEncestors (getApplicationContext (), Object.class): getApplicationContext (). GetBeanNamesFortype (object.class); untuk (string beanName: beannames) {if (isHandler (getApplicationContext (). getType (beanname))) {detecthandlermethods (beanname); }} handlermethodsinitialized (getHandlermethods ());}Dalam metode ISHandler, kami akan menentukan apakah anotasi kacang saat ini adalah pengontrol. Kode sumber adalah sebagai berikut:
Boolean Ishandler yang dilindungi (kelas <?> beantype) {return annotationutils.findannotation (beantype, controller.class)! = null;}Dalam konfigurasi langkah ke -4, semua kacang dengan anotasi @Controller juga terdaftar dalam wadah SpringMVC, sehingga SpringMVC dapat menemukan prosesor untuk diproses, sehingga melompat secara normal.
Kami menemukan alasan mengapa tidak dapat melompat dengan benar, jadi apa solusinya?
Kami memperhatikan bahwa dalam metode inithandlermethods (), detecthandlermethodsinancestorcontexts switch, terutama mengontrol kacang mana dalam wadah diperoleh dan apakah wadah induk disertakan. Itu tidak termasuk secara default. Jadi solusinya adalah mengkonfigurasi properti detecthandlermethodsinancestorcontexts dari handlermapping ke true dalam file konfigurasi springmvc (di sini Anda perlu melihat jenis handlermapping mana yang digunakan sesuai dengan proyek tertentu), sehingga dapat mendeteksi kacang dari wadah induk. sebagai berikut:
<Bean> <name properti = "detecthandlermethodsinancestorcontexts"> <value> true </ value> </property> </ bean>
Namun, dalam proyek aktual, akan ada banyak konfigurasi. Kami membagi berbagai jenis kacang dalam wadah yang berbeda sesuai dengan rekomendasi resmi sesuai dengan modul bisnis yang berbeda: Kontainer induk musim semi bertanggung jawab atas pendaftaran semua kacang lain yang tidak dijelaskan oleh @Controller, sementara SpringMVC hanya bertanggung jawab atas pendaftaran kacang. Metode konfigurasi adalah sebagai berikut
1. Konfigurasikan di ApplicationContext.xml:
<!-Daftarkan kacang dalam wadah musim semi yang tidak dijelaskan oleh @Controller-> <Context: komponen-scan-package = "com.hafiz.www"> <konteks: Kecualikan filter type = "annotation" expression = "org.springframework.steretype.controller"//</Context: component-scan>
2. Konfigurasi di ApplicationContext-Mvc.xml
<!-Hanya kacang dengan anotasi @Controller yang terdaftar dalam wadah SpringMVC-> <konteks: komponen-scan-package = "com.hafiz.www" penggunaan-default-filters = "false"> <Contact: include-filter type = "annotation" expression = "org.springframework.steretyple.cordroller =" annotation "expression =" org.springframework.steretyple.cordroller = "organ" organ /org
3. Ringkasan
Dengan cara ini, setelah kami memahami hubungan wadah orangtua-anak antara Spring dan SpringMVC dan prinsip pemindaian dan pendaftaran, menurut saran resmi, kami dapat mengalokasikan berbagai jenis kacang ke berbagai kontainer untuk manajemen. Jika ada masalah seperti kacang tidak dapat ditemukan, SpringMVC tidak dapat dialihkan, dan konfigurasi transaksi gagal, kita dapat dengan cepat menemukan dan menyelesaikan masalah. Sangat senang, apakah ada ~
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.