这是使用Guice在Tomcat上运行的webapp。根据文档,我们应该能够调用ResourceBundle.clearCache();
来清除ResourceBundle缓存,并且可能从bundle属性文件中获取最新信息。
我们还尝试了以下方法:
Class klass = ResourceBundle.getBundle("my.bundle").getClass().getSuperclass();
Field field = klass.getDeclaredField("cacheList");
field.setAccessible(true);
ConcurrentHashMap cache = (ConcurrentHashMap) field.get(null);
cache.clear(); // If i debug here I can see the cache is now empty!
和
ResourceBundle.clearCache(this.class.getClassLoader());
我期待的行为是:
所以问题是,ResourceBundle.clearCache()实际上是如何工作的?还有一些我们需要清除的通用文件缓存吗?
答案 0 :(得分:6)
这对我有用:
ResourceBundle.clearCache();
ResourceBundle resourceBundle= ResourceBundle.getBundle("YourBundlePropertiesFile");
String value = resourceBundle.getString("your_resource_bundle_key");
备注:强>
ResourceBundle.getBundle()
后的clearCache()
方法
方法答案 1 :(得分:4)
我不相信你可以影响已经创建的ResourceBundle实例的重新加载,因为它已经创建了它的内部控件类。您可以尝试将此作为初始化捆绑包的替代方法:
ResourceBundle.getBundle("my.bundle", new ResourceBundle.Control() {
@Override
public long getTimeToLive(String arg0, Locale arg1) {
return TTL_DONT_CACHE;
}
});
答案 2 :(得分:1)
我找到了这个解决方案(适用于tomcat):
如何致电:
ResourceBundle bundle = ResourceBundle.getBundle("yourfile", new UTF8Control());
自定义类:
public class UTF8Control extends Control
{
public ResourceBundle newBundle(
String baseName,
Locale locale,
String format,
ClassLoader loader,
boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
// FORCE RELOAD because needsReload doesn't work and reload is always false
reload = true;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
}
else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
}
finally {
stream.close();
}
}
return bundle;
}
// ASK NOT TO CACHE
public long getTimeToLive(String arg0, Locale arg1) {
return TTL_DONT_CACHE;
}
}
答案 3 :(得分:0)
也许this post可以解决您的问题。
答案 4 :(得分:0)
this is one more possibility to clear cache
Class<ResourceBundle> type = ResourceBundle.class;
try {
Field cacheList = type.getDeclaredField("cacheList");
cacheList.setAccessible(true);
((Map<?, ?>) cacheList.get(ResourceBundle.class)).clear();
}
catch (Exception e) {
system.out.print("Failed to clear ResourceBundle cache" + e);
}
答案 5 :(得分:0)
如果您可以拦截资源包的第一次创建,则此方法有效:
while (true) {
ResourceBundle resourceBundle = ResourceBundle.getBundle("SystemMessages", new Locale("hu", "HU"),
new ResourceBundle.Control() {
@Override
public List<String> getFormats(String baseName) {
return ResourceBundle.Control.FORMAT_PROPERTIES;
}
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
System.err.println(this.toBundleName(baseName, locale) + ": " + format + " - " + reload);
return super.newBundle(baseName, locale, format, loader, reload);
}
@Override
public long getTimeToLive(String baseName, Locale locale) {
long ttl = 1000;
System.err.println(this.toBundleName(baseName, locale) + " - " + ttl + "ms");
return ttl;
}
@Override
public boolean needsReload(String baseName, Locale locale, String format, ClassLoader loader, ResourceBundle bundle, long loadTime) {
System.err.println(baseName + "_" + locale + " - " + new Date(loadTime));
return true;
}
});
System.out.println(resourceBundle.getString("display.first_name") + ": John");
System.out.println(resourceBundle.getString("display.last_name") + ": Doe");
Thread.sleep(5000);
}