1. Pencegat dan filter
Sebelum berbicara tentang Spring Boot, mari kita lihat filter dan pencegat. Keduanya sangat mirip dalam hal fungsi, tetapi masih ada kesenjangan besar dalam implementasi teknis tertentu. Sebelum menganalisis perbedaan antara keduanya, mari kita pahami pertama konsep AOP. AOP bukanlah teknologi khusus, tetapi ide pemrograman. Dalam proses pemrograman yang berorientasi objek, mudah bagi kita untuk menyelesaikan ekspansi vertikal melalui pewarisan dan polimorfisme. Namun, untuk fungsi horizontal, seperti memungkinkan transaksi dalam semua metode layanan, atau penebangan terpadu, fungsi yang berorientasi objek tidak dapat diselesaikan. Oleh karena itu, pemrograman yang berorientasi AOP sebenarnya merupakan suplemen untuk gagasan pemrograman yang berorientasi objek. Filter dan pencegat yang kita bicarakan hari ini adalah implementasi spesifik dari pemrograman yang berorientasi aspek. Perbedaan utama antara keduanya termasuk aspek -aspek berikut:
1. Filter tergantung pada wadah servlet dan merupakan bagian dari spesifikasi servlet. Pencegat ada secara mandiri dan dapat digunakan dalam keadaan apa pun.
2. Eksekusi filter diselesaikan oleh callback wadah servlet, dan interseptor biasanya dieksekusi melalui proxy dinamis.
3. Siklus hidup filter dikelola oleh wadah servlet, sedangkan pencegat dapat dikelola melalui wadah IOC. Oleh karena itu, contoh kacang lain dapat diperoleh melalui injeksi dan metode lainnya, sehingga akan lebih nyaman untuk digunakan.
2. Konfigurasi Filter
Sekarang kami menggunakan filter untuk mewujudkan fungsi merekam waktu eksekusi permintaan, yang diimplementasikan sebagai berikut:
LogCostFilter kelas publik mengimplementasikan filter {@Override public void init (filterconfig filterconfig) melempar servletException {} @Override public void dofilter (servletRequest servletRequest, servletResponse response (filterChain chilterChain) lemparan ioeksepsi (servletResception {pilterChainChain) lemparan ioException, servletexception {pilterChainChain) lemparan ioException, servletexception {pilterChainChain) lemparan ioException, servletexception {pilterChainChain) lemparan ioException (servletexcepion {sver filterchain.dofilter (servletRequest, servletResponse); System.out.println ("Execute cost ="+(System.currentTimeMillis ()-start)); } @Override public void destrash () {}}Logika kode ini relatif sederhana, yaitu untuk mencatat stempel waktu sebelum metode dijalankan, dan kemudian menyelesaikan pelaksanaan permintaan melalui rantai filter, dan menghitung waktu eksekusi antara hasil yang dikembalikan. Hal utama di sini adalah bahwa kelas ini harus mewarisi kelas filter. Ini adalah spesifikasi Servlet, yang tidak berbeda dari proyek web sebelumnya. Namun, dengan kelas filter, proyek web sebelumnya dapat dikonfigurasi di web.xml, tetapi proyek Spring Boot tidak memiliki file web.xml, jadi bagaimana cara mengkonfigurasinya? Di Spring Boot, kita membutuhkan filterregistrationBean untuk menyelesaikan konfigurasi. Proses implementasi adalah sebagai berikut:
@ConfigurationPublic kelas filterconfig {@Bean filterregistrationBean RegistrationFilter () {filterRegistrationBean Registration = new FilterRegistrationBean (); Registrasi.SetFilter (LogCostFilter () baru); Registrasi.addurlPatterns ("/*"); Registrasi.SetName ("LogCostFilter"); Registrasi.Setorder (1); pendaftaran kembali; }}Konfigurasi ini selesai. Opsi yang perlu dikonfigurasi terutama mencakup instantiasi kelas filter, kemudian menentukan pola pencocokan URL, mengatur nama filter dan urutan eksekusi. Proses ini sebenarnya tidak berbeda dengan konfigurasi di web.xml, tetapi formulirnya hanya berbeda. Sekarang kita dapat memulai server untuk mengakses URL apa pun:
Anda dapat melihat bahwa konfigurasi di atas telah berlaku. Selain mengonfigurasi melalui filterregistrationBean, ada juga cara yang lebih langsung, yang dapat diselesaikan langsung melalui anotasi:
@WebFilter (urlpatterns = "/*", filtername = "logfilter2") kelas publik logcostfilter2 mengimplementasikan filter {@override public init (filterconfig filterconfig) Layanan servletseption {} @Override void dofilter (servletRequestse, servletponseVonseConse (servletsequestse, servletponse publicponse (servlleteConseConsception {} LAVERCONCONSE (LAYAN LAVERREXE (LAYERVONCONCONCONCONCONCEVERCE (LAGERCONCONCECCEVIG {@Override IoException, servletException {long start = system.currentTimeMillis (); filterchain.dofilter (servletRequest, servletResponse); System.out.println ("LogFilter2 mengeksekusi biaya =" + (System.currentTimeMillis () - start)); } @Override public void destrash () {}}Di sini Anda dapat mengonfigurasinya secara langsung dengan @WebFilter. Demikian pula, Anda dapat mengatur mode pencocokan URL, nama filter, dll. Satu hal yang perlu diperhatikan di sini adalah bahwa anotasi @WebFilter adalah spesifikasi dari Servlet 3.0 dan tidak disediakan oleh Spring Boot. Selain anotasi ini, kita juga perlu menambahkan anotasi lain ke kelas konfigurasi: @servletcomponetscan, menentukan paket yang dipindai.
@SpringbootApplication@mapperscan ("com.pandy.blog.dao")@servletComponentscan ("com.pandy.blog.filters") Aplikasi kelas publik {public static Main (String [] args) melempar pengecualian {springapplication.run (application.class, args); }} Sekarang, mari kita kunjungi URL lagi:
Seperti yang Anda lihat, kedua filter yang kami konfigurasi telah berlaku. Pembaca yang cermat akan menemukan bahwa kami tidak menentukan urutan eksekusi filter kedua, tetapi jalankan sebelum filter pertama. Harus dijelaskan di sini bahwa anotasi @WebFilter tidak menentukan atribut urutan eksekusi. Urutan eksekusi tergantung pada nama filter dan diatur dalam urutan terbalik berdasarkan urutan abjad dari nama kelas filter (perhatikan bahwa itu bukan nama filter yang dikonfigurasi). Prioritas filter yang ditentukan oleh @WebFilter lebih tinggi dari filter yang dikonfigurasi oleh filterregistrationBean. Teman yang tertarik dapat bereksperimen sendiri.
3. Konfigurasi Interceptor
Kami telah memperkenalkan metode konfigurasi filter di atas. Selanjutnya, mari kita lihat cara mengkonfigurasi pencegat. Kami menggunakan pencegat untuk mengimplementasikan fungsi yang sama di atas, merekam waktu eksekusi permintaan. Pertama kami mengimplementasikan kelas pencegat:
LogCostInceptor kelas publik mengimplementasikan HandlerInterceptor {Long Start = System.CurrentTimeMillis (); @Override Public boolean prehandle (httpservletRequest httpservletRequest, httpservletResponse httpservletResponse, objek o) melempar pengecualian {start = system.currentTimeMillis (); Kembali Benar; } @Override public void posthandle (httpservletRequest httpservletRequest, httpservletResponse httpservletResponse, objek o, model dan model model dan lemparan pengecualian {system.out.println ("interceptor cost =" +current {System.out.println ("startceptor cost =" +current {System.out) ("startEmeMeMiLN (" startem ("startEmeMiLN (" startem ("startem (" startem ("start) (system. } @Override public void aftercompletion (httpservletRequest httpservletRequest, httpservletResponse httpservletResponse, objek o, pengecualian e) melempar pengecualian {}}Di sini kita perlu menerapkan antarmuka handlerinterceptor. Antarmuka ini mencakup tiga metode. Prehandle dieksekusi sebelum permintaan dieksekusi, dan postandler dieksekusi setelah permintaan dieksekusi, tetapi hanya akan dieksekusi ketika metode prehandle mengembalikan true. AfterCompletion dieksekusi setelah rendering tampilan selesai. Prehandle juga perlu mengembalikan true. Metode ini biasanya digunakan untuk sumber daya pembersih dan tugas -tugas lainnya. Selain menerapkan antarmuka di atas, kita juga perlu mengonfigurasinya:
@ConfigurationPublic kelas intercepTorConfig memperluas WebMvCconfigurerAdapter {@Override public void addInterceptors (intercepTorRegistry registry) {Registry.AddInterceptor (LogCostInterceptor baru ()). AddPathPatterns ("/**"); Super.AddInterceptors (Registry); }}Di sini kami mewarisi WebMvCconfigurerAdapter. Teman -teman yang telah membaca artikel sebelumnya seharusnya melihat kelas ini. Kami telah menggunakan kelas ini saat mengkonfigurasi direktori sumber daya statis. Di sini kami telah menulis ulang metode AddInterceptors untuk mengonfigurasi interseptor. Ada dua item konfigurasi utama: satu adalah untuk menentukan interseptor dan yang lainnya adalah menentukan URL pencegat. Sekarang kami memulai sistem dan mengakses URL apa pun:
Seperti yang Anda lihat, kami mencapai fungsi yang sama melalui pencegat. Namun, perlu dicatat di sini bahwa implementasi ini sebenarnya bermasalah, karena Prehandle dan Posthandle adalah dua metode, jadi kami harus menetapkan variabel bersama untuk menyimpan nilai awal, tetapi ini akan memiliki masalah keamanan utas. Tentu saja, kita dapat menyelesaikan masalah ini melalui metode lain, seperti Threadlocal, yang dapat diselesaikan dengan baik, dan siswa yang tertarik dapat mengimplementasikannya sendiri. Namun, melalui ini kita benar -benar dapat melihat bahwa meskipun pencegat lebih baik daripada filter dalam banyak skenario, dalam skenario ini, filter lebih sederhana untuk diterapkan daripada pencegat.
4. Ringkasan
Artikel ini terutama menjelaskan konfigurasi filter dan pencegat berdasarkan boot musim semi. Baik filter dan pencegat termasuk dalam implementasi spesifik ide AOP (pemrograman berorientasi sectional). Selain dua implementasi ini, kami juga telah melihat teknologi implementasi AOP lain yang lebih fleksibel, yaitu aspek, di mana kami dapat menyelesaikan fungsi yang lebih dan lebih kuat melalui aspek. Saya akan membagikan ini dengan Anda nanti.