【问题标题】:Reloading Properties files when changed更改时重新加载属性文件
【发布时间】:2012-11-28 16:42:29
【问题描述】:

我正在将属性文件加载到一个类,然后在整个应用程序中使用该类来获取它们。

public class PropertiesUtil extends PropertyPlaceholderConfigurer {

    private static Map<String, String> properties = new HashMap<String, String>();

    @Override
    protected void loadProperties(final Properties props) throws IOException {
        super.loadProperties(props);
        for (final Object key : props.keySet()) {
            properties.put((String) key, props.getProperty((String) key));
        }
    }

    public String getProperty(final String name) {
        return properties.get(name);
    }

}

在 ApplicationContext.xml 中

    <bean id="propertiesUtil"
        class="com.test.PropertiesUtil">
        <property name="locations">
            <list>
                <value>classpath:test/test.properties</value>
            </list>
        </property>
    </bean>

现在我想确保属性文件在更改时重新加载。

我有一个与 tomcat 服务器一起初始化的侦听器类。 我已经为文件观察器编写了以下逻辑

TimerTask task = new FileWatcher(new File("c:\\temp-reb\\config\\config.properties")) {
    /*
     * (non-Javadoc)
     * @see com.belgacom.rosy.rebecca.utils.FileWatcher#onChange(java.io.File)
     */
    @Override
    protected void onChange(File file) {
        loadServiceProperties(file);
        loadMetadata();
    }
};

Timer timer = new Timer();
timer.schedule(task, new Date(), Long.valueOf(properties.getProperty("properties.file.timer.schedule"))); // repeat the check every second

问题是

  1. FileWatcher 需要路径才能运行,我不想硬编码
  2. 如何告诉 spring 调用属性以显式重新加载!

【问题讨论】:

    标签: java spring file properties


    【解决方案1】:
    1. FileWatcher 需要运行路径,我不想硬编码

    只需提供相对路径,如同一项目文件夹中的资源目录,您可以使用getResource() 方法获取。您也可以使用system property 来访问user.dir,这是使用工作目录。

    File f = new File(System.getProperty("user.dir")+ "/test.properties");
    System.out.println(f.getAbsolutePath());
    

    2。我如何告诉 spring 调用属性以显式重新加载!

    你目前的做法对我来说似乎没问题。可能还有其他方法,但我没有看到上述过程中有任何缺陷。

    【讨论】:

    • FileWatcher 接受 File 作为参数。我可以将字符串传递给 File。但是 getResource() 不会正确返回其中任何一个。
    • 应该使用 File.separator 而不是 "/"
    【解决方案2】:

    这是一条蜿蜒曲折的道路,通往真正黑暗的地方。 Spring 每个定义都会实例化并维护对单例的引用。因此,如果客户端注入了依赖项并保留它,并且应用程序上下文开始提供新的 bean,那么您将处于一个非常丑陋的状态。如果您不将属性用作 bean 属性,则应该没问题,但是混合这并不是真正的方法。

    如果有的话,我会尝试限制受重新加载属性影响的 bean 数量并将它们放在特殊范围内。这样,每当您的范围发生变化时,您都会获得一个具有最新配置的新 bean。至少您将拥有已定义的属性生命周期,并且确切地知道您要面对什么。

    【讨论】:

    • 对不起,我没有得到你太多。我的监听器类/线程将在服务器启动期间启动一次并且永远不会结束(是的,它在无限循环上运行它自己的工作),我需要在这个线程中执行文件观察器/重新加载属性。它不像普通的网络应用程序。但我想实现上述要求,即每当属性更改时,加载它们。能指导一下吗?
    • 如果你是 Batchig,看看 Spring Batch。如果您在命令行应用程序上运行,请在每个周期之前终止应用程序上下文并使用所有依赖 bean 重新加载它,前提是您可以承受性能开销。
    • 它是网络应用程序。某事不应该停止
    • 您要替换什么样的属性?它们如何影响系统?
    • 可以将应用程序过程从一个方向更改为另一个方向的属性。
    猜你喜欢
    • 2017-01-16
    • 2012-05-07
    • 1970-01-01
    • 2019-09-24
    • 2020-10-06
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多