ResourceBundle 实现定时重载 properties 文件

来源:互联网 发布:淘宝网店没人 编辑:程序博客网 时间:2024/06/04 18:08

之前我们介绍了《使用 Commons Configuration 自动重载配置文件》,此方法不适合在多语言环境下,因为同一个 Properties 文件,我们经常有多种语言的版本,例如 ui.properties 、ui_zh_CN.properties 、 ui_en.properties 等。

而 ResourceBundle 是实现自动加载多语言版本 properties 文件的不二之选。

但我们又对 ResourceBundle 提出了更高的要求,要求能自动重载更改后的 properties 文件,而无需重启应用。

在 JDK 1.6 中,新增了一个类 ResourceBundle.Control 可实现简单的自动重载,其实这是一个实现控制 ResourceBundle缓存策略的类。该类有两个方法涉及到缓存:getTimeToLive、needsReload

其中 getTimeToLive 方法表示 ResourceBundle 实例在缓存中存在的时间,可以是某个具体的微秒值,也可以是不缓存(TTL_DONT_CACHE ),或者永久缓存(TTL_NO_EXPIRATION_CONTROL)。

一旦设置了具体的微秒值时,假设 getTimeToLive 返回的是1000,那么每次在调用 getBundle 的时候,每隔 1 秒钟就会调用另外一个 needsReload 方法来判断是否需要重新加载 ResourceBundle 。needsReload只返回 true 或者 false,表示是否重加载。

但是 ResourceBundle.Control 这个缓存控制策略又有很多不足,首先,ResourceBundle 无法与所对应的 properties 文件的实例对应起来,也就是说我无法根据 properties 的最后修改时间来决定是否重新加载文件。这就是我说的最大的不足。

但是聊胜于无吧,在生产环境中我们可以将 getTimeToLive 值设得稍微大一些,例如1分钟或者更多。这样 properties 文件修改一分钟后就会被自动加载。

下面是一个简单的演示例子:
package net.oschina.tester;

import java.util.Locale;
import java.util.ResourceBundle;

/**
 * ResourceBundle 重载测试
 * @author Winter Lau
 * @date 2010-5-12 下午11:00:55
 */
public class ResourceTester {

 private final static MyResourceBundleControl ctl = new MyResourceBundleControl();
 
 /**
  * @param args
  * @throws InterruptedException
  */
 public static void main(String[] args) throws InterruptedException {
  System.out.println(getBundle().getString("email"));
  Thread.sleep(2000);
  System.out.println(getBundle().getString("email"));
 }
 
 private static ResourceBundle getBundle(){
  return ResourceBundle.getBundle("ui", Locale.getDefault(), ctl);
 }

 /**
  * 重载控制器,每秒钟重载一次
  * @author Winter Lau
  * @date 2010-5-12 下午11:20:02
  */
 private static class MyResourceBundleControl extends ResourceBundle.Control {

  /**
   * 每一秒钟检查一次
   */
  @Override
  public long getTimeToLive(String baseName, Locale locale) {
   return 1000;
  }

  @Override
  public boolean needsReload(String baseName, Locale locale,
    String format, ClassLoader loader,
    ResourceBundle bundle, long loadTime) {
   return true;
  }
 }
 
}

 

如果能实现 ResourceBundle 跟 Commons Configuration 项目进行结合,那就秒多了。

原创粉丝点击