Если вы используете журнал в качестве компонента выхода в своем приложении, большинство из них настроят файл `regback.xml`. Кроме того, в производственной среде вы можете напрямую изменить уровень журнала в файле regaback.xml, и он может вступить в силу без перезапуска приложения. Итак, как реализована эта функция?
Если вы используете журнал в качестве компонента выхода в своем приложении, большинство из них настроят файл regaback.xml. Кроме того, в производственной среде вы можете напрямую изменить уровень журнала в файле regaback.xml, и он может вступить в силу без перезапуска приложения.
Итак, как реализована эта функция?
I. Описание и анализ проблем
В ответ на вышеупомянутую проблему сначала бросьте фактический случай. На моем личном веб -сайте Z+все гаджеты добавляются динамически и скрыты через файлы конфигурации. Поскольку существует только один сервер, файлы конфигурации упрощены и размещаются непосредственно в каталоге на сервере.
Теперь, когда у меня есть проблема, мне нужно реализовать изменение при изменении содержания этого файла, приложение может ощутить изменение, перезагрузить содержимое файла и обновить внутренний кэш приложения
Одним из самых простых способов придумать является опрос, чтобы определить, был ли файл изменен. Если он будет изменен, он будет перезагружен и обновлен. Следовательно, основные проблемы, которые должны быть обеспокоены следующими:
II Проектирование и реализация
После того, как проблема абстрагирована, соответствующее решение является более четким
Тогда очень простая реализация проще:
открытый класс Fileuptest {private Long в прошлый раз; @Test public void testfileupdate () {file file = new File ("/tmp/callistconfig"); // сначала последняя измененная временная метка файла прошлого года = file.lastmodified (); // Временная задача определяет, изменялся ли файл каждую секунду, то есть определяет, можно ли засновные изменения warededexecutorservice gadeledexecutorservice = executors.newschedledThreadpool (1); PredicleDexeCutorService.scheduleAtFixedRate (new Runnable () {@Override public void run () {if (file.lastmodified ()> в прошлый раз) {System.out.println ("Обновление файла! Time:" + file.lastmodified ()); прошлый раз = file.lastmodified (); TimeUnit.seconds); try {thread.sleep (1000 * 60); } catch (прерванное искусство e) {e.printstacktrace (); }}}Выше приведено очень простая и очень базовая реализация, которая в основном может удовлетворить наши потребности. Так в чем же проблема с этой реализацией?
Что произойдет, если возникает исключение во время выполнения задачи времени?
Внесите некоторые изменения в вышеупомянутый код
открытый класс Fileuptest {private Long в прошлый раз; private void tt () {бросить новый NullPointerException (); } @Test public void testFileUpdate () {file file = new File ("/tmp/callistconfig"); прошедшее время = file.lastmodified (); Gadulledexecutorservice seduledexecutorservice = experators.newschedledthreadpool (1); warededExecutorservice.scheduleatfixedrate (new Runnable () {@override public void run () {if (file.lastmodified ()> в прошлый раз) {System.out.println ("Обновление файла! Time:" + file.lastmodified ()); 1 -й файл. TimeUnit.seconds); try {thread.sleep (1000 * 60 * 10); } catch (прерванное искусство e) {e.printstacktrace (); }}}В фактическом тесте я обнаружил, что приведенный выше код был запускается только тогда, когда первая модификация была изменена, но изменение снова будет бесполезно. То есть, когда было брошено исключение, задача времени больше не будет выполнена. Основная причина этой проблемы заключается в том, что PreduledExecutorService
Ознакомьтесь с инструкциями по комментарию исходного кода.
Если какое -либо выполнение задачи встречает исключение, последующие выполнения подавляются. Иногда задача будет прекращена только путем отмены или прекращения завершения исполнителя.
Поэтому при использовании этой позы вы должны убедиться, что ваша задача не бросает исключения, иначе вы не сможете играть позже
Соответствующее решение относительно простое, просто поймайте его
Iii. Усовершенствованное издание
Предыдущий является основной версией реализации. Конечно, в круге Java существует в основном много распространенных потребностей, которые можно найти для использования соответствующих инструментов с открытым исходным кодом. Конечно, это не исключение, и это должна быть серия Apache, что у каждого больше атрибутов.
Прежде всего, зависимости Maven
<Depective> <groupid> commons-io </GroupId> <artifactid> commons-io </artifactid> <sersion> 2.6 </version> </depervice>
В основном мы используем в этом инструменте FlieLaterationObserver, FileartationSlistener и FileartationMonitor для реализации сценариев соответствующих требований. Конечно, это очень просто в использовании, поэтому я не знаю, как это объяснить. Просто посмотрите на код, скопированный из одного из моего проекта с открытым исходным кодом.
Public Class PropertiesConflistenerHelper {public Static Boolean RegisterConfChangelistener (файл файла, функция <файл, карта <строка, callerconfig >> func) {try {// Интервал опроса 5 секунд длиной интервал = timeUnit.seconds.tomillis (5); // Поскольку прослушивание выполняется в каталогах, корневой каталог файла напрямую получен здесь файл dir = file.getParentFile (); // Создать файловый наблюдатель для фильтрации FilalterationObserver vasever = new FilealterationObserver (dir, filefilterutils.and (filefilterutils.filefilefilter (), filefilterutils.namefilefilter (file.getname ()))); // Установить изменение файла прослушивание stuster.addlistener (new MyFileListener (func)); FileartationMonitor Monitor = new FileartationMonitor (интервал, наблюдатель); monitor.start (); вернуть истину; } catch (Exception e) {log.error ("Свойства регистра изменять ошибку прослушивателя! e: {}", e); вернуть ложь; }} Статический окончательный класс myFileListener Extends filalterationStisterEneNaptor {Private Function <file, map <string, callistconfig >> func; public myFileListener (function <файл, карта <string, armerConfig >> func) {this.func = func; } @Override public void OnFileChange (файл файла) {map <string, armerConfig> ans = func.apply (file); // Если загрузка не сбои, распечатайте журнал log.warn ("PropertiesConfig изменил! Перезагрузить ANS: {}", ANS); }}}Для приведенной выше реализации несколько кратких объяснений:
Вопрос, что произойдет, если исключение брошено при выполнении метода фанка?
Фактические результаты теста такие же, как и выше. После того, как вы добавили исключение, вы все равно должны быть осторожны и не запускать исключение.
Итак, давайте посмотрим на вышеуказанную логику реализации и прямо вычесть основной модуль.
public void run () {while (true) {if (this.running) {iterator var1 = this.observers.iterator (); while (var1.hasnext ()) {fliealtatorationObserver stemver = (filealterationObserver) var1.next (); stemver.checkandNotify (); } if (this.running) {try {thread.sleep (this.Interval); } catch (прерванное разложение var3) {; } продолжать; } } возвращаться; }}В основном из вышеперечисленного, что вся логика реализации отличается от нашего первого метода задачи. Здесь мы используем потоки и мертвые петли напрямую, и методы сна используются для приостановки внутри страны. Следовательно, когда происходит исключение, оно эквивалентно бросанию его напрямую, и нить опустится на колени.
Дополнительная версия JDK
JDK1.7 предоставляет наблюдательный сервис, который также может использоваться для мониторинга изменений файлов. Я не подвергался этому раньше, поэтому я узнал, что есть эта вещь. Затем я искал информацию, связанную с использованием, и обнаружил, что она довольно просто. Я видел сообщение в блоге, которое объясняет, что он основан на событиях и обладает более высокой эффективностью. Вот простой пример демонстрации
@Testpublic void testfileupwather () бросает ioexception {// инструкции, слушатель здесь также должен быть пути пути каталога = paths.get ("/tmp"); WatchService Watcher = fileSystems.getDefault (). NewWatchService (); path.register (Watcher, entry_modify); new Thread (() -> {try {while (true) {watchkey key = watcher.take (); for (watchevent <?> Event: key.pollevents ()) {if (event.kind () == overflow) {// Событие может быть потеряно или отброшено продолжение;} pathename = (path) event.context (); } if (! try {thread.sleep (1000 * 60 * 10); } catch (прерванное искусство e) {e.printstacktrace (); }}IV Краткое содержание
Использование Java для реализации мониторинга изменений файлов конфигурации в основном включает в себя две точки
В целом, эта реализация относительно проста. Будь то пользовательская реализация или полагаться на Comso-IO, она не имеет особого технического затрат, но одно нужно отметить:
Чтобы избежать вышеуказанной ситуации, реализация, которая может быть выполнена, состоит в том, чтобы использовать асинхронное уведомление о сообщении о событиях. После изменения файла отправьте сообщение, а затем добавьте аннотацию @SubScribe в конкретный метод перезагрузки содержимого файла. Это не только осознает развязку, но и избегает исключений услуг, вызванных исключениями (если вы заинтересованы в этой реализации, вы можете комментировать и объяснить)
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.