<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 自動重新加載屬性的 Java `WatchService`示例 > 原文: [https://howtodoinjava.com/java7/auto-reload-of-configuration-when-any-change-happen/](https://howtodoinjava.com/java7/auto-reload-of-configuration-when-any-change-happen/) **每當配置文件**中發生任何更改時,都會自動刷新這些文件 – 這是大多數應用程序中常見的一個常見問題。 每個應用程序都有一些配置,預期該配置文件中的每次更改都會刷新。 解決該問題的過去方法包括使用`Thread`,它根據配置文件的*最后更新時間戳*定期輪詢文件更改。 現在使用 Java 7,情況已經改變。 Java 7 引入了一項出色的特性:[**`WatchService`**](https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html)。 我將盡力為您解決上述問題。 這可能不是最好的實現,但是肯定會為您的解決方案提供一個很好的開始。 我敢打賭! ```java Table of Contents: 1) A brief overview of WatchService 2) Writing our configuration provider 3) Introducing configuration change listener 4) Testing our code 5) Key notes ``` ## 1\. Java `WatchService` API `WatchService`是 JDK 的內部服務,監視注冊對象的更改。 這些注冊的對象必定是[`Watchable`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/Watchable.html "Watchable interface")接口的實例。 在`WatchService`中注冊`Watchable`實例時,我們需要指定我們感興趣的變更事件的類型。 到目前為止,有四種類型的事件: 1. [`ENTRY_CREATE`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardWatchEventKinds.html#ENTRY_CREATE "ENTRY_CREATE") , 2. [`ENTRY_DELETE`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardWatchEventKinds.html#ENTRY_DELETE "ENTRY_DELETE") , 3. [`ENTRY_MODIFY`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardWatchEventKinds.html#ENTRY_MODIFY "ENTRY_MODIFY") 和 4. [`OVERFLOW`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardWatchEventKinds.html#OVERFLOW "OVERFLOW")。 您可以在提供的鏈接中了解這些事件。 `WatchService`接口擴展了[`Closeable`](https://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html "Closable interface")接口,表示可以根據需要關閉服務。 通常,應該使用 JVM 提供的關閉掛鉤來完成。 ## 2\. 應用程序配置供應器 配置供應器只是用于包裝[`java.util.Properties`](https://docs.oracle.com/javase/6/docs/api/java/util/Properties.html "java util Properties")實例中的屬性集的包裝器。 它還提供了使用**鍵**來獲取已配置屬性的方法。 ```java package testWatchService; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ApplicationConfiguration { private final static ApplicationConfiguration INSTANCE = new ApplicationConfiguration(); public static ApplicationConfiguration getInstance() { return INSTANCE; } private static Properties configuration = new Properties(); private static Properties getConfiguration() { return configuration; } public void initilize(final String file) { InputStream in = null; try { in = new FileInputStream(new File(file)); configuration.load(in); } catch (IOException e) { e.printStackTrace(); } } public String getConfiguration(final String key) { return (String) getConfiguration().get(key); } public String getConfigurationWithDefaultValue(final String key, final String defaultValue) { return (String) getConfiguration().getProperty(key, defaultValue); } } ``` ## 3\. 配置更改監聽器 – 文件監視器 現在,當我們有了配置屬性的內存中緩存的基本包裝器時,我們需要一種機制,只要存儲在文件系統中的配置文件發生更改,就可以在運行時重新加載此緩存。 我已經寫了一個示例工作代碼來為您提供幫助: ```java package testWatchService; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; public class ConfigurationChangeListner implements Runnable { private String configFileName = null; private String fullFilePath = null; public ConfigurationChangeListner(final String filePath) { this.fullFilePath = filePath; } public void run() { try { register(this.fullFilePath); } catch (IOException e) { e.printStackTrace(); } } private void register(final String file) throws IOException { final int lastIndex = file.lastIndexOf("/"); String dirPath = file.substring(0, lastIndex + 1); String fileName = file.substring(lastIndex + 1, file.length()); this.configFileName = fileName; configurationChanged(file); startWatcher(dirPath, fileName); } private void startWatcher(String dirPath, String file) throws IOException { final WatchService watchService = FileSystems.getDefault() .newWatchService(); Path path = Paths.get(dirPath); path.register(watchService, ENTRY_MODIFY); Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { watchService.close(); } catch (IOException e) { e.printStackTrace(); } } }); WatchKey key = null; while (true) { try { key = watchService.take(); for (WatchEvent<?> event : key.pollEvents()) { if (event.context().toString().equals(configFileName)) { configurationChanged(dirPath + file); } } boolean reset = key.reset(); if (!reset) { System.out.println("Could not reset the watch key."); break; } } catch (Exception e) { System.out.println("InterruptedException: " + e.getMessage()); } } } public void configurationChanged(final String file) { System.out.println("Refreshing the configuration."); ApplicationConfiguration.getInstance().initilize(file); } } ``` 上面的類是使用線程創建的,該線程將使用`WatchService`監聽配置屬性文件的更改。 一旦檢測到文件中的任何修改,它便會刷新配置中的內存緩存。 上述監聽器的構造器僅采用一個參數,即受監視的配置文件的標準路徑。 在文件系統中更改配置文件時,會立即通知`Listener`類。 然后,此監聽器類調用`ApplicationConfiguration.getInstance().initilize(file);`以重新加載到內存緩存中。 ## 4\. 測試我們的代碼 現在,當我們準備好類時,我們將對其進行測試。 首先,將`test.properties`文件及其以下內容存儲在`'C:/Lokesh/temp'`文件夾中。 ```java TEST_KEY=TEST_VALUE ``` 現在,讓我們使用以下代碼測試以上類。 ```java package testWatchService; public class ConfigChangeTest { private static final String FILE_PATH = "C:/Lokesh/temp/test.properties"; public static void main(String[] args) { ConfigurationChangeListner listner = new ConfigurationChangeListner( FILE_PATH); try { new Thread(listner).start(); while (true) { Thread.sleep(2000l); System.out.println(ApplicationConfiguration.getInstance() .getConfiguration("TEST_KEY")); } } catch (Exception e) { e.printStackTrace(); } } } //Output of the above program (Change the TEST_VALUE to TEST_VALUE1 and TEST_VALUE2 using any file editor and save). Refreshing the configuration. TEST_VALUE TEST_VALUE TEST_VALUE Refreshing the configuration. TEST_VALUE1 Refreshing the configuration. TEST_VALUE2 ``` 以上輸出表明,每次我們對屬性文件進行任何更改時,刷新的屬性都會刷新,并且可以使用新的屬性值。 到目前為止,已經做好了! ## 5\. 重要說明 1. 如果在新項目中使用 Java 7,并且沒有在使用老式方法重新加載屬性,則說明操作不正確。 2. `WatchService`提供了兩個方法[`take()`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html#take%28%29 "Watch Service take method")和[`poll()`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html#take%28%29 "watch Service poll method")。當`take()`方法等待下一次更改發生并被阻止之前,`poll()`立即檢查更改事件。 如果上次`poll()`調用沒有任何變化,它將返回 `null`。 `poll()`方法不會阻止執行,因此應在具有一些睡眠時間的線程中調用。 將我的問題/建議放在評論區。 學習愉快!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看