Jika Anda menggunakan logback sebagai komponen logout di aplikasi Anda, kebanyakan dari mereka akan mengkonfigurasi file `logback.xml`. Selain itu, di lingkungan produksi, Anda dapat secara langsung memodifikasi level log dalam file logback.xml, dan dapat berlaku tanpa memulai kembali aplikasi. Jadi, bagaimana fungsi ini diimplementasikan?
Jika Anda menggunakan logback sebagai komponen logout di aplikasi Anda, kebanyakan dari mereka akan mengkonfigurasi file logback.xml. Selain itu, di lingkungan produksi, Anda dapat secara langsung memodifikasi level log dalam file logback.xml, dan dapat berlaku tanpa memulai kembali aplikasi.
Jadi, bagaimana fungsi ini diimplementasikan?
I. Deskripsi dan analisis masalah
Menanggapi masalah di atas, pertama -tama lemparkan kasus yang sebenarnya. Di situs web pribadi saya Z+, semua gadget ditambahkan secara dinamis dan disembunyikan melalui file konfigurasi. Karena hanya ada satu server, file konfigurasi disederhanakan dan ditempatkan langsung di direktori di server.
Sekarang ketika saya memiliki masalah, saya perlu mewujudkan perubahan ketika konten file ini berubah, aplikasi dapat merasakan perubahan, memuat ulang konten file, dan memperbarui cache internal aplikasi
Salah satu cara termudah untuk dipikirkan adalah pemungutan suara untuk menentukan apakah file telah dimodifikasi. Jika dimodifikasi, itu akan dimuat ulang dan disegarkan. Oleh karena itu, masalah utama yang perlu diperhatikan adalah sebagai berikut:
Ii. Desain dan Implementasi
Setelah masalah diabstraksi, solusi yang sesuai lebih jelas
Maka implementasi yang sangat sederhana lebih mudah:
Public Class FileUPTest {Private Long Last Time; @Test public void testFileUpdate () {file file = file baru ("/tmp/alarmconfig"); // Pertama, cap waktu terakhir yang dimodifikasi dari file terakhir kali = file.lastmodified (); // Tugas waktunya, menentukan apakah file telah berubah setiap detik, yaitu, menentukan apakah perubahan yang terakhir dimodifikasi dijadwalkan ExcecutorService Dijadwalkan ExecutorService = Executors.newscheduledThreadPool (1); SCRETDUREDEXECURTERVICE.SCHEDULULEATFIXEDRATE (RUNNABLE BARU () {@Override public void run () {if (File.LastModified ()> LastTime) {System.out.println ("File Update! Time:" + File.LastModified ()); LastTime = File.LastModified Timeunit.seconds); coba {thread.sleep (1000 * 60); } catch (InterruptedException e) {E.PrintStackTrace (); }}}Di atas adalah implementasi yang sangat sederhana dan sangat mendasar, yang pada dasarnya dapat memenuhi kebutuhan kita. Jadi apa masalah dengan implementasi ini?
Apa yang terjadi jika pengecualian terjadi selama pelaksanaan tugas waktu?
Membuat beberapa modifikasi pada kode di atas
Public Class FileUPTest {Private Long Last Time; private void tt () {lempar nullpointerException baru (); } @Test public void testFileUpdate () {file file = file baru ("/tmp/alarmconfig"); lastTime = file.lastModified (); Terjadwal executorService Dijadwalkan executorService = executors.newscheduledThreadpool (1); scheduledExecutorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { if (file.lastModified() > lastTime) { System.out.println("file update! time : " + file.lastModified()); lastTime = file.lastModified(); ttt(); } } } }, 0, 1, Timeunit.seconds); coba {thread.sleep (1000 * 60 * 10); } catch (InterruptedException e) {E.PrintStackTrace (); }}}Dalam tes aktual, saya menemukan bahwa kode di atas dipicu hanya ketika modifikasi pertama dimodifikasi, tetapi modifikasi lagi tidak akan berguna. Yaitu, ketika pengecualian dilemparkan, tugas waktu tidak lagi dieksekusi. Alasan utama untuk masalah ini adalah bahwa jadwal executorservice adalah
Lihat instruksi komentar kode sumber dari jadwal executorservice secara langsung
Jika ada pelaksanaan tugas yang menemukan pengecualian, eksekusi selanjutnya ditekan. Selain itu, tugas hanya akan berakhir melalui pembatalan atau penghentian pelaksana.
Oleh karena itu, saat menggunakan postur ini, Anda harus memastikan bahwa tugas Anda tidak melempar pengecualian, jika tidak, Anda tidak akan dapat bermain nanti
Solusi yang sesuai relatif sederhana, tangkap saja
AKU AKU AKU. Edisi Lanjutan
Yang sebelumnya adalah versi implementasi dasar. Tentu saja, di lingkaran Java, pada dasarnya ada banyak kebutuhan umum yang dapat ditemukan menggunakan alat sumber terbuka yang sesuai. Tentu saja, ini tidak terkecuali, dan itu harus menjadi seri Apache yang setiap orang memiliki lebih banyak atribut.
Pertama -tama, dependensi Maven
<dependency> <GroupId> Commons -o </GroupId> <ArTifactId> Commons -o </artifactid> <version> 2.6 </version> </dependency>
Terutama, kami menggunakan filealterationObserver, FilealterationListener, dan filealerationMonitor dalam alat ini untuk mengimplementasikan skenario persyaratan terkait. Tentu saja, sangat mudah digunakan, jadi saya tidak tahu bagaimana menjelaskannya. Lihat saja kode yang disalin dari salah satu Proyek Open Source saya Quick-Alarm.
Public Class PropertiesConflistenHelper {public static boolean registerconfChangeListener (file file, fungsi <file, peta <string, alarmconfig >> func) {try {// interval pemungutan suara 5 detik interval panjang = timeunit.seconds.tomillis (5); // Karena mendengarkan dilakukan di direktori, direktori root file secara langsung diperoleh di sini file dir = file.getParentFile (); // Buat pengamat file untuk memfilter FilealterationObserver Observer = FilealterationObserver baru (dir, filefilterutils.and (filefilterutils.filefilterter (), filefilterutils.namefilefilter (file.getName ())))); // Setel File Change Listener Observer.AddListener (myFileListener baru (func)); FilealterationationMonitor Monitor = FilealterationationMonitor baru (Interval, Observer); monitor.start (); Kembali Benar; } catch (Exception e) {log.error ("Daftar properti mengubah kesalahan pendengar! E: {}", e); mengembalikan false; }} kelas akhir statis myfileListener memperluas filealterationListenerAdaptor {function private <file, peta <string, alarmconfig>> func; public myfileListener (fungsi <file, peta <string, alarmconfig>> func) {this.func = func; } @Override public void onFileChange (file file) {peta <string, alarmconfig> ans = func.Apply (file); // Jika memuat gagal, cetak log log.warn ("PropertiesConfig diubah! Reload ANS: {}", ANS); }}}Untuk implementasi di atas, beberapa penjelasan singkat:
Sebuah pertanyaan, apa yang terjadi jika pengecualian dilemparkan ketika metode FUNC dieksekusi?
Hasil tes yang sebenarnya sama seperti di atas. Setelah melempar pengecualian, Anda masih harus berhati -hati dan tidak menjalankan pengecualian.
Jadi, mari kita lihat logika implementasi di atas dan secara langsung mengurangi modul inti.
public void run () {while (true) {if (this.running) {iterator var1 = this.observer.iterator (); while (var1.hasnext ()) {filealterationObserver Observer = (filealterationObserver) var1.next (); Observer.CheckandNotify (); } if (this.running) {coba {thread.sleep (this.interval); } catch (InterruptedException var3) {; } melanjutkan; } } kembali; }}Pada dasarnya jelas dari atas bahwa seluruh logika implementasi berbeda dari metode tugas waktu pertama kami. Di sini kami menggunakan benang dan loop mati secara langsung, dan metode tidur digunakan untuk berhenti secara internal. Oleh karena itu, ketika pengecualian terjadi, setara dengan melemparkannya secara langsung, dan utas akan berlutut.
Versi JDK Tambahan
JDK1.7 menyediakan layanan jam, yang juga dapat digunakan untuk memantau perubahan file. Saya belum pernah terpapar sebelumnya, jadi saya tahu ada hal ini. Kemudian saya mencari informasi terkait penggunaan dan menemukan bahwa itu cukup sederhana. Saya melihat posting blog yang menjelaskan itu adalah acara dan memiliki efisiensi yang lebih tinggi. Berikut adalah contoh demo sederhana
@Testpublic void testfileupwather () melempar ioException {// instruksi, pendengar di sini juga harus menjadi jalur direktori = paths.get ("/tmp"); WatchService Watcher = FileSystems.getDefault (). NewWatchService (); path.register (pengamat, entri_modify); utas baru (() -> {coba {while (true) {watchkey key = watcher.take (); untuk (watchevent <?> event: key.pollevents ()) {if (event.kind () == overflow) {// event dapat hilang atau dibuang lanjutkan;} path fileName = (Path) event.context); } if (! key.reset ()) {// Reset WatchKey Break; coba {thread.sleep (1000 * 60 * 10); } catch (InterruptedException e) {E.PrintStackTrace (); }}Iv. Ringkasan
Menggunakan Java untuk mengimplementasikan pemantauan perubahan file konfigurasi terutama melibatkan dua titik
Secara keseluruhan, implementasi ini relatif sederhana. Apakah itu implementasi khusus atau mengandalkan Commos-OO, itu tidak memiliki banyak biaya teknis, tetapi satu hal yang perlu diperhatikan adalah:
Untuk menghindari situasi di atas, implementasi yang dapat dilakukan adalah dengan menggunakan pemberitahuan pesan Asynchronous dari Eventbus. Setelah file berubah, kirim pesan, dan kemudian tambahkan anotasi @subscribe ke metode spesifik untuk memuat ulang konten file. Ini tidak hanya menyadari decoupling, tetapi juga menghindari pengecualian layanan yang disebabkan oleh pengecualian (jika Anda tertarik dengan implementasi ini, Anda dapat berkomentar dan menjelaskan)
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.