Apache的Commons-configuration自动加载(刷新)特性

在一些项目可能可能会使用一些配置文件,配置文件的类型可能为xml,或者properties文件等,可以采用Apache 的commons-confiugrations实现相关的功能。http://blog.csdn.net/buyaore_wo/article/details/6203022

如果这些配置文件要经常变化,我们系统会自动检测到配置文件的变化,自动更新到内存等中,可能这样做:

PropertiesConfiguration config = new PropertiesConfiguration("config.properties");
config.setReloadingStrategy(new FileChangedReloadingStrategy());

那么它是怎么做到的自动重载呢:看下源码:

org.apache.commons.configuration.AbstractFileConfiguration中的部分方法

    public void reload()
    {
        synchronized (reloadLock)
        {
            if (noReload == 0)
            {
                try
                {
                    enterNoReload(); // avoid reentrant calls

                    if (strategy.reloadingRequired())
                    {
                        if (getLogger().isInfoEnabled())
                        {
                            getLogger().info("Reloading configuration. URL is " + getURL());
                        }
                        fireEvent(EVENT_RELOAD, null, getURL(), true);
                        setDetailEvents(false);
                        boolean autoSaveBak = this.isAutoSave(); // save the current state
                        this.setAutoSave(false); // deactivate autoSave to prevent information loss
                        try
                        {
                            clear();
                            load();
                        }
                        finally
                        {
                            this.setAutoSave(autoSaveBak); // set autoSave to previous value
                            setDetailEvents(true);
                        }
                        fireEvent(EVENT_RELOAD, null, getURL(), false);

                        // notify the strategy
                        strategy.reloadingPerformed();
                    }
                }
                catch (Exception e)
                {
                    fireError(EVENT_RELOAD, null, null, e);
                    // todo rollback the changes if the file can't be reloaded
                }
                finally
                {
                    exitNoReload();
                }
            }
        }
    }

 //............

    public Object getProperty(String key)
    {
        synchronized (reloadLock)
        {
            reload();
            return super.getProperty(key);
        }
    }

    public boolean isEmpty()
    {
        reload();
        return super.isEmpty();
    }

    public boolean containsKey(String key)
    {
        reload();
        return super.containsKey(key);
    }


看到在取数据之前它都有一相reload,看到这里 我们明白他不是主被的定期地去重新加载文件,而是在使用是被动的去重新加载的,

而判断是否要重新加载的重点是红色部分: 我们再看FileChangedReloadingStrategy中方法:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.configuration.reloading;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.commons.configuration.ConfigurationUtils;
import org.apache.commons.configuration.FileConfiguration;

/**
 * <p>A reloading strategy that will reload the configuration every time its
 * underlying file is changed.</p>
 * <p>This reloading strategy does not actively monitor a configuration file,
 * but is triggered by its associated configuration whenever properties are
 * accessed. It then checks the configuration file's last modification date
 * and causes a reload if this has changed.</p>
 * <p>To avoid permanent disc access on successive property lookups a refresh
 * delay can be specified. This has the effect that the configuration file's
 * last modification date is only checked once in this delay period. The default
 * value for this refresh delay is 5 seconds.</p>
 * <p>This strategy only works with FileConfiguration instances.</p>
 *
 * @author Emmanuel Bourg
 * @version $Revision: 606798 $, $Date: 2007-12-25 20:05:58 +0100 (Di, 25 Dez 2007) $
 * @since 1.1
 */
public class FileChangedReloadingStrategy implements ReloadingStrategy
{
    /** Constant for the jar URL protocol.*/
    private static final String JAR_PROTOCOL = "jar";

    /** Constant for the default refresh delay.*/
    private static final int DEFAULT_REFRESH_DELAY = 5000;

    /** Stores a reference to the configuration to be monitored.*/
    protected FileConfiguration configuration;

    /** The last time the configuration file was modified. */
    protected long lastModified;

    /** The last time the file was checked for changes. */
    protected long lastChecked;

    /** The minimum delay in milliseconds between checks. */
    protected long refreshDelay = DEFAULT_REFRESH_DELAY;

    /** A flag whether a reload is required.*/
    private boolean reloading;

    public void setConfiguration(FileConfiguration configuration)
    {
        this.configuration = configuration;
    }

    public void init()
    {
        updateLastModified();
    }

    public boolean reloadingRequired()
    {
        if (!reloading)
        {
            long now = System.currentTimeMillis();

            if (now > lastChecked + refreshDelay)
            {
                lastChecked = now;
                if (hasChanged())
                {
                    reloading = true;
                }
            }
        }

        return reloading;
    }

    public void reloadingPerformed()
    {
        updateLastModified();
    }

    /**
     * Return the minimal time in milliseconds between two reloadings.
     *
     * @return the refresh delay (in milliseconds)
     */
    public long getRefreshDelay()
    {
        return refreshDelay;
    }

    /**
     * Set the minimal time between two reloadings.
     *
     * @param refreshDelay refresh delay in milliseconds
     */
    public void setRefreshDelay(long refreshDelay)
    {
        this.refreshDelay = refreshDelay;
    }

    /**
     * Update the last modified time.
     */
    protected void updateLastModified()
    {
        File file = getFile();
        if (file != null)
        {
            lastModified = file.lastModified();
        }
        reloading = false;
    }

    /**
     * Check if the configuration has changed since the last time it was loaded.
     *
     * @return a flag whether the configuration has changed
     */
    protected boolean hasChanged()
    {
        File file = getFile();
        if (file == null || !file.exists())
        {
            return false;
        }

        return file.lastModified() > lastModified;
    }

    /**
     * Returns the file that is monitored by this strategy. Note that the return
     * value can be <b>null </b> under some circumstances.
     *
     * @return the monitored file
     */
    protected File getFile()
    {
        return (configuration.getURL() != null) ? fileFromURL(configuration
                .getURL()) : configuration.getFile();
    }

    /**
     * Helper method for transforming a URL into a file object. This method
     * handles file: and jar: URLs.
     *
     * @param url the URL to be converted
     * @return the resulting file or <b>null </b>
     */
    private File fileFromURL(URL url)
    {
        if (JAR_PROTOCOL.equals(url.getProtocol()))
        {
            String path = url.getPath();
            try
            {
                return ConfigurationUtils.fileFromURL(new URL(path.substring(0,
                        path.indexOf('!'))));
            }
            catch (MalformedURLException mex)
            {
                return null;
            }
        }
        else
        {
            return ConfigurationUtils.fileFromURL(url);
        }
    }
}

他一开始就记录文件最后更新的时间,在读取属性是会判断文件是更新时间是否已经大于内存中保存的时间,如果大于将会重新加载配置


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值