我们正在使用java.util.ResourceBundle
加载属性信息。我们的属性文件变得如此庞大,我们正在考虑将主属性文件拆分为几个子模块。有可能实现这一目标吗?
master.properties
==>
master.properties
include moduleA.properties
include moduleB.properties
让我知道?
我们正在使用java.util.ResourceBundle
加载属性信息。我们的属性文件变得如此庞大,我们正在考虑将主属性文件拆分为几个子模块。有可能实现这一目标吗?
master.properties
==>
master.properties
include moduleA.properties
include moduleB.properties
让我知道?
首先,我想知道你为什么选择java.util.ResourceBundle
了java.util.Properties
. 鉴于您的问题是如何制定的,您似乎并不关心本地化/国际化,也不关心捆绑文件继承。
Properties
它非常容易,因为它实现了Map
反过来提供了putAll()
一种合并另一个地图的方法。开球示例:
Properties master = new Properties();
master.load(masterInput);
Properties moduleA = new Properties();
moduleA.load(moduleAinput);
master.putAll(moduleA);
Properties moduleB = new Properties();
moduleB.load(moduleBinput);
master.putAll(moduleB);
// Now `master` contains the properties of all files.
如果您真的坚持使用ResourceBundle
,最好的办法是创建一个自定义ResourceBundle
,其中您可以通过自定义控制加载Control
。
假设您有以下条目,master.properties
其中表示一个逗号分隔的字符串,其中包含模块属性文件的基本名称:
include=moduleA,moduleB
那么下面的自定义ResourceBundle
示例应该可以工作:
public class MultiResourceBundle extends ResourceBundle {
protected static final Control CONTROL = new MultiResourceBundleControl();
private Properties properties;
public MultiResourceBundle(String baseName) {
setParent(ResourceBundle.getBundle(baseName, CONTROL));
}
protected MultiResourceBundle(Properties properties) {
this.properties = properties;
}
@Override
protected Object handleGetObject(String key) {
return properties != null ? properties.get(key) : parent.getObject(key);
}
@Override
@SuppressWarnings("unchecked")
public Enumeration<String> getKeys() {
return properties != null ? (Enumeration<String>) properties.propertyNames() : parent.getKeys();
}
protected static class MultiResourceBundleControl extends Control {
@Override
public ResourceBundle newBundle(
String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
Properties properties = load(baseName, loader);
String include = properties.getProperty("include");
if (include != null) {
for (String includeBaseName : include.split("\\s*,\\s*")) {
properties.putAll(load(includeBaseName, loader));
}
}
return new MultiResourceBundle(properties);
}
private Properties load(String baseName, ClassLoader loader) throws IOException {
Properties properties = new Properties();
properties.load(loader.getResourceAsStream(baseName + ".properties"));
return properties;
}
}
}
(无关紧要的异常处理和本地化处理,这取决于你)
这可以用作:
ResourceBundle bundle = new MultiResourceBundle("master");
但是,您可以以编程方式构造 ResourceBundle 但正如您所说的那样,您的文件很大,那么如果将其加载到内存中会怎样。
更新
public class Resource extends java.util.ResourceBundle {
public Object handleGetObject(String key) {
//code
}
public Enumeration getKeys() {
//code
}
}
然后对于 IN 语言环境
import java.util.*;
public class Resource_en_IN extends Resource{
public Object handleGetObject(String key) {
//code
}
}
比经过测试的解决方案更值得深思。
XML 文件支持实体在解析期间内联来自其他文件的文本。如果看到复杂的 xml 文件,其中已使用此技术对文件进行模块化。
Properties
现在支持两种文件格式,.properties
键/值对的通用格式和 xml 格式。Properties
可以加载和存储到/从xml文件。
ResourceBundle
有一个直接子类:PropertyResourceBundle
. 看起来这个类实际上仅限于较旧的键/值对格式,但它可以用于实现另一个类,例如XMLPropertyResourceBundle
能够从 xml 文件中读取属性的entity
技巧可以帮助模块化这些文件。
如果这可行 - 将现有属性文件转换为 xml 属性文件应该很容易,只需使用Properties
该类,从标准格式读取并存储到 XML。