首页 > 代码库 > ResourceBundle 实现定时重载 properties 文件
ResourceBundle 实现定时重载 properties 文件
简介
在 JDK 1.6 中,新增了一个类 ResourceBundle.Control 可实现简单的自动重载,其实这是一个实现控制 ResourceBundle 缓存策略的类。该类有两个方法涉及到缓存:getTimeToLive、needsReload
其中 getTimeToLive 方法表示 ResourceBundle 实例在缓存中的生存时间,可以是某个具体的微秒值,也可以是不缓存(TTL_DONT_CACHE),或者永久缓存(TTL_NO_EXPIRATION_CONTROL)。
一旦设置了具体的微秒值时,假设 getTimeToLive 返回的是1000,那么每次在调用 getBundle 的时候,只要当前时间和载入资源的时间之差比TimeToLive要大,就要调用needsReload 方法来判断是否需要重新加载 ResourceBundle 。needsReload只返回 true 或者 false,表示是否重加载。
源码浅析
我们可以通过源码来看看具体的逻辑:(不感兴趣可以跳到最后直接看如何定时重载properties文件)
1、首先当我们没有禁用缓存时,首次加载资源文件时,系统会将文件缓存,此时会为缓存设置一个过期时间,而这个过期时间就是根据TimeToLive加上当前时间算出来的:
private static final void setExpirationTime(CacheKey cacheKey, Control control) { long ttl = control.getTimeToLive(cacheKey.getName(), cacheKey.getLocale()); if (ttl >= 0) { // If any expiration time is specified, set the time to be // expired in the cache. long now = System.currentTimeMillis(); cacheKey.loadTime = now; cacheKey.expirationTime = now + ttl; } else if (ttl >= Control.TTL_NO_EXPIRATION_CONTROL) { cacheKey.expirationTime = ttl; } else { throw new IllegalArgumentException("Invalid Control: TTL=" + ttl); } }
2、而我们调用getBundle(..)去获取资源包时,首先会去缓存中找,若找到了,还需要判断是否超时,超时了就要判断是否过期(是否需要重载)
synchronized (bundle) { expirationTime = key.expirationTime; if (!bundle.expired && expirationTime >= 0 && expirationTime <= System.currentTimeMillis()) { try {// 超时之后判断needToReload,这个返回true才是真正的过期 bundle.expired = control.needsReload(key.getName(), key.getLocale(), key.getFormat(), key.getLoader(), bundle, key.loadTime); } catch (Exception e) { cacheKey.setCause(e); } if (bundle.expired) { // If the bundle needs to be reloaded, then // remove the bundle from the cache, but // return the bundle with the expired flag // on. bundle.cacheKey = null; cacheList.remove(cacheKey, bundleRef); } else { // Update the expiration control info. and reuse // the same bundle instance setExpirationTime(key, control); } } }
3、若需要重载的话,那就重新加载资源
定时重载 properties 文件
根据上面说的,我们只需要实现自己的Control就可以了package bundle.test; import java.util.Locale; import java.util.ResourceBundle; /** * 自动刷新资源文件 * @author Zhu * */ 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("cancelKey")); Thread.sleep(5000); System.out.println(getBundle().getString("cancelKey")); } private static ResourceBundle getBundle() { return ResourceBundle.getBundle("res", Locale.getDefault(), ctl); } /** * 重载控制器 */ 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; } } }
这样只要间隔时间超过1s去访问资源包,都能取到最新的~
ResourceBundle 实现定时重载 properties 文件
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。