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

2022-07-22  本文已影响0人  ShootHzj

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();
    }

}
上一篇下一篇

猜你喜欢

热点阅读