美文网首页
java实现两种方式自动刷新配置文件

java实现两种方式自动刷新配置文件

作者: ShootHzj | 来源:发表于2022-07-22 09:31 被阅读0次

    java实现两种方式自动刷新读取配置文件,本文代码已经上传到gitee,以如下的有两个属性的简单配置文件为例

    name=hzj
    age=18
    

    手动书写配置文件刷新逻辑

    使用定时任务+AtomicRerence实现配置文件刷新

    package com.shoothzj.man;
    
    import java.io.File;
    import java.util.Properties;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicReference;
    
    public class ConfigReaderMan {
    
        private final String path;
    
        private final AtomicReference<Properties> confRef = new AtomicReference<>();
    
        private final ScheduledExecutorService executor;
    
        public ConfigReaderMan(String path, int period, TimeUnit timeUnit) {
            this.path = path;
            loadConf();
            executor = Executors.newSingleThreadScheduledExecutor();
            executor.scheduleWithFixedDelay(this::loadConf, period, period, timeUnit);
        }
    
        private void loadConf() {
            try {
                Properties conf = new Properties();
                conf.load(new File(path).toURI().toURL().openStream());
                confRef.set(conf);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public String getName() {
            return confRef.get().getProperty("name");
        }
    
        public int getAge() {
            return Integer.parseInt(confRef.get().getProperty("age"));
        }
    
        public void close() {
            executor.shutdown();
        }
    
    }
    

    对应测试用例如下

    package com.shoothzj.cc2;
    
    import org.assertj.core.util.Files;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.concurrent.TimeUnit;
    
    class ConfigReaderCc2Test {
    
        @Test
        public void testReloadConfig() {
            File file = Files.newTemporaryFile();
            file.deleteOnExit();
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write("name=hzj\n".getBytes());
                fos.write("age=18\n".getBytes());
            } catch (Exception e) {
                Assertions.fail(e.getMessage());
            }
            ConfigReaderCc2 reader = new ConfigReaderCc2(file.getAbsolutePath(), 1, TimeUnit.MILLISECONDS);
            Assertions.assertEquals("hzj", reader.getName());
            Assertions.assertEquals(18, reader.getAge());
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write("name=jzh\n".getBytes());
                fos.write("age=81\n".getBytes());
                fos.flush();
            } catch (Exception e) {
                Assertions.fail(e.getMessage());
            }
            // sleep five seconds to make sure the config file is reloaded
            try {
                Thread.sleep(5_000);
            } catch (InterruptedException e) {
                Assertions.fail(e.getMessage());
            }
            Assertions.assertEquals("jzh", reader.getName());
            Assertions.assertEquals(81, reader.getAge());
            reader.close();
        }
    
    }
    

    使用commons-configuration2+AtomicReference实现配置文件刷新

    package com.shoothzj.cc2;
    
    import org.apache.commons.configuration2.BaseConfiguration;
    import org.apache.commons.configuration2.Configuration;
    import org.apache.commons.configuration2.PropertiesConfiguration;
    import org.apache.commons.configuration2.builder.ConfigurationBuilderEvent;
    import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
    import org.apache.commons.configuration2.builder.fluent.Parameters;
    import org.apache.commons.configuration2.ex.ConfigurationException;
    import org.apache.commons.configuration2.reloading.PeriodicReloadingTrigger;
    
    import java.io.File;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicReference;
    
    public class ConfigReaderCc2 {
    
        private final AtomicReference<Configuration> confRef = new AtomicReference<>();
    
        private final ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration> builder = new ReloadingFileBasedConfigurationBuilder<>(PropertiesConfiguration.class);
    
        private final PeriodicReloadingTrigger trigger;
    
        public ConfigReaderCc2(String path, int period, TimeUnit timeUnit) {
            Parameters parameters = new Parameters();
            builder.configure(parameters.fileBased().setFile(new File(path)));
            builder.addEventListener(ConfigurationBuilderEvent.RESET, event -> {
                System.out.println("config.properties has been reloaded");
                confRef.set(loadConf());
            });
            trigger = new PeriodicReloadingTrigger(builder.getReloadingController(), null, period, timeUnit);
            trigger.start();
            confRef.set(loadConf());
        }
    
        private Configuration loadConf() {
            try {
                return builder.getConfiguration();
            } catch (ConfigurationException e) {
                System.err.println("load configuration failed " + e);
                return new BaseConfiguration();
            }
        }
    
        public String getName() {
            return confRef.get().getString("name");
        }
    
        public int getAge() {
            return confRef.get().getInt("age");
        }
    
        public void close() {
            trigger.shutdown();
        }
    
    }
    

    对应测试用例如下

    package com.shoothzj.man;
    
    import org.assertj.core.util.Files;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.concurrent.TimeUnit;
    
    class ConfigReaderManTest {
    
        @Test
        public void testReloadConfig() {
            File file = Files.newTemporaryFile();
            file.deleteOnExit();
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write("name=hzj\n".getBytes());
                fos.write("age=18\n".getBytes());
            } catch (Exception e) {
                Assertions.fail(e.getMessage());
            }
            ConfigReaderMan reader = new ConfigReaderMan(file.getAbsolutePath(), 1, TimeUnit.MILLISECONDS);
            Assertions.assertEquals("hzj", reader.getName());
            Assertions.assertEquals(18, reader.getAge());
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write("name=jzh\n".getBytes());
                fos.write("age=81\n".getBytes());
                fos.flush();
            } catch (Exception e) {
                Assertions.fail(e.getMessage());
            }
            // sleep five seconds to make sure the config file is reloaded
            try {
                Thread.sleep(5_000);
            } catch (InterruptedException e) {
                Assertions.fail(e.getMessage());
            }
            Assertions.assertEquals("jzh", reader.getName());
            Assertions.assertEquals(81, reader.getAge());
            reader.close();
        }
    
    }
    

    相关文章

      网友评论

          本文标题:java实现两种方式自动刷新配置文件

          本文链接:https://www.haomeiwen.com/subject/mptbirtx.html