Commons Configuration2 ReloadingFileBasedConfiguration

时间:2016-04-19 22:53:04

标签: apache-commons

我正在尝试在我的代码库中实现Apache Configuration 2

import java.io.File;
import java.util.concurrent.TimeUnit;

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.convert.DefaultListDelimiterHandler;
import org.apache.commons.configuration2.event.EventListener;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.reloading.PeriodicReloadingTrigger;

import org.apache.commons.configuration2.CompositeConfiguration;

public class Test {

    private static final long DELAY_MILLIS = 10 * 60 * 5;


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
        PropertiesConfiguration props = null;
        try {
            props = initPropertiesConfiguration(new File("/tmp/DEV.properties"));
        } catch (ConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        compositeConfiguration.addConfiguration( props );
        compositeConfiguration.addEventListener(ConfigurationBuilderEvent.ANY,
                new EventListener<ConfigurationBuilderEvent>()
                {
                    @Override
                    public void onEvent(ConfigurationBuilderEvent event)
                    {
                        System.out.println("Event:" + event);

                    }
                });

        System.out.println(compositeConfiguration.getString("property1"));

        try {
            Thread.sleep(14*1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Have a script which changes the value of property1 in DEV.properties
        System.out.println(compositeConfiguration.getString("property1"));
    }

    protected static PropertiesConfiguration initPropertiesConfiguration(File propsFile) throws ConfigurationException { 

        if(propsFile.exists()) {

            final ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration> builder =
                    new ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class)
                    .configure(new Parameters().fileBased()
                        .setFile(propsFile)
                        .setReloadingRefreshDelay(DELAY_MILLIS)
                        .setThrowExceptionOnMissing(false)
                        .setListDelimiterHandler(new DefaultListDelimiterHandler(';')));
            final PropertiesConfiguration propsConfiguration = builder.getConfiguration();
            PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(builder.getReloadingController(),
                    null, 1, TimeUnit.SECONDS);
                trigger.start();

            return propsConfiguration;
        } else {
            return new PropertiesConfiguration();
        }

    }
}

以下是我用来检查自动重新加载是否有效的示例代码。但是,当更新基础属性文件时,配置不会反映它。

2 个答案:

答案 0 :(得分:5)

根据文件:

  

使用此方法重新加载时要记住的一个重点是,只有将构建器用作访问配置数据的中央组件时,重新加载才有效。从构建器获取的配置实例不会自动更改!因此,如果应用程序在启动时从构建器中提取配置对象,然后在其整个生命周期内使用它,则外部配置文件上的更改将永远不可见。正确的方法是集中保留对构建器的引用,并在每次需要配置数据时从那里获取配置。

https://commons.apache.org/proper/commons-configuration/userguide/howto_reloading.html#Reloading_File-based_Configurations

这与旧的实现不同。

我能够通过进行2次更改成功执行您的示例代码:

  1. 使构建器全局可用并从构建器访问配置:

    System.out.println(builder.getConfiguration().getString("property1"));

  2. 将侦听器添加到构建器: `builder.addEventListener(ConfigurationBuilderEvent.ANY,new EventListener(){

        public void onEvent(ConfigurationBuilderEvent event) {
            System.out.println("Event:" + event);
        }
    });
    
  3. 发布我的示例程序,我能够成功演示它

    import java.io.File;
    import java.util.concurrent.TimeUnit;
    
    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.event.EventListener;
    import org.apache.commons.configuration2.reloading.PeriodicReloadingTrigger;
    
    public class TestDynamicProps {
        public static void main(String[] args) throws Exception {
    
            Parameters params = new Parameters();
            ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration> builder =
                new ReloadingFileBasedConfigurationBuilder<PropertiesConfiguration>(PropertiesConfiguration.class)
                .configure(params.fileBased()
                    .setFile(new File("src/main/resources/override.properties")));
            PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(builder.getReloadingController(),
                null, 1, TimeUnit.SECONDS);
            trigger.start();
    
            builder.addEventListener(ConfigurationBuilderEvent.ANY, new EventListener<ConfigurationBuilderEvent>() {
    
                public void onEvent(ConfigurationBuilderEvent event) {
                    System.out.println("Event:" + event);
                }
            });
    
            while (true) {
                Thread.sleep(1000);
                System.out.println(builder.getConfiguration().getString("property1"));
            }
    
        }
    }
    

答案 1 :(得分:-2)

您的实现的问题是,重新加载是在ReloadingFileBasedConfigurationBuilder对象上完成的,并且没有返回到PropertiesConfiguration对象。