如何引用java.util.Properties中的另一个属性?

Java属性文件可以引用其他属性文件吗?

## define a default directory for Input files dir.default=/home/data/in/ dir.proj1=${dir.default}p1 dir.proj2=${dir.default}p2 dir.proj3=${dir.default}p3 

这可能吗?

这是你想要的,有点旧了,但可能会满足你的需求。

在属性值中启用常量replace

您可以在属性值的任何位置replace一个常量,并且在一个值内甚至可以有多个常量,如下例所示:

 CONST_1 = shoes and ships CONST_2 = sealing wax SomeValue = {CONST_1} and {CONST_2} 

在这个例子中,“SomeValue”属性评估为“鞋和船舶和封蜡”。

Eproperties是一个开源项目 ,它提供了variablesreplace以及其他一些特性 – 尽pipereplace可能是最有用的。 它是java.util.Properties的一个子类,可以被任何其他可以将configuration信息作为Properties的类使用。

标准属性文件只是键值对。 在文本格式中, Properties只是将键与值分开,并执行一些简单的操作,例如允许转义字符。 您可以使用详细的XML语法来定义实体。

如果你想要自己的replace语法,那么你可以像处理任何其他string一样操纵返回的值。 或者,您可以编写自己的版本的Properties或生成文件时进行replace。

Commons Config lib也可以这样做。 http://commons.apache.org/configuration/userguide/overview.html#Using_Configuration

不过,正如已经指出的那样,看看EProperties库吧; http://code.google.com/p/eproperties/

它支持许多整洁的特性(如replace,嵌套,列表),包括包含,扩展Java属性,比Commons Config(它也允许你使用include语法包含属性)轻了一些。

java.util.Properties类不会为你做这个。 子类的属性不会太困难,重写load()方法并自己进行replace。

由于eproperties是有点不维护和commonsconfiguration依赖于日志logging(具有讽刺意味的是你不能用它来configuration日志logging)我使用这个代码片段,只需要commons-lang(3)加载插值的属性:

 @SuppressWarnings("serial") public static Map<String,String> loadPropertiesMap(InputStream s) throws IOException { final Map<String, String> ordered = new LinkedHashMap<String, String>(); //Hack to use properties class to parse but our map for preserved order Properties bp = new Properties() { @Override public synchronized Object put(Object key, Object value) { ordered.put((String)key, (String)value); return super.put(key, value); } }; bp.load(s); final Map<String,String> resolved = new LinkedHashMap<String, String>(ordered.size()); StrSubstitutor sub = new StrSubstitutor(new StrLookup<String>() { @Override public String lookup(String key) { String value = resolved.get(key); if (value == null) return System.getProperty(key); return value; } }); for (String k : ordered.keySet()) { String value = sub.replace(ordered.get(k)); resolved.put(k, value); } return resolved; } 

input

 blah=${user.dir} one=1 two=2 five=5 fifteen=${one}${five} twoonefive=${two}${fifteen} six=6 

输出

 blah=/current/working/dir one=1 two=2 five=5 fifteen=15 twoonefive=215 six=6 

很明显Map<String,String>如果你需要的话Map<String,String>你可以将Map<String,String>转换回一个Properties对象。 我根据先前声明的属性和系统属性来parsing,但是您可以明显地在StrSubstitutor.lookup调整它。

在这种特殊情况下(以及其他情况),您最好通过定义不同的属性来解决重复问题:

  1. dir.proj1=dir.default /p1更改为dir.proj1_extension=/p1
  2. prepend: dir.defaultdir.proj1_extension以获取应用程序代码中proj1的完整位置。

为其他项目做同样的事情。

下面是Java中的代码片段,用于读取引用其他属性的属性。 具体来说,这些是可重用的查询,但也可以是其他的东西。

 LinkedHashMap<String, String> sqlsRaw = loadPropertiesFromFile(); LinkedHashMap<String, String> sqls = new LinkedHashMap<>(); StrSubstitutor substitutor = new StrSubstitutor(sqls); for (Map.Entry<String, String> entry : sqlsRaw.entrySet()) { String sql = entry.getValue(); try { sql = substitutor.replace(sql); } catch (Exception e) { throw new RuntimeException("Found an sql with a non replaced reference to another. Please validate that the required key was defined before this sql: " + entry.getValue(), e); } sqls.put(entry.getKey(), sql); } 

示例属性:

 key1=value1 key21=value2 ${key1} 

运行这个之后, key21的值是value2 value1

*使用Apache的StrSubstitutor