类型安全配置 - 从 map/file 解析并解析

Typesafe config - parse from map/file and resolve

我可以在从字符串解析配置时解析替换,但在从映射或文件解析时不能。

import java.io.File
import com.typesafe.config.{Config, ConfigFactory}
import scala.collection.JavaConversions.mapAsJavaMap

val s: String = "a = test, b = another ${a}"
val m: Map[String, String] = Map("a" -> "test", "b" -> "another ${a}")
val f: File = new File("test.properties") // contains "a = test\nb = another ${a}"

val cs: Config = ConfigFactory.parseString(s).resolve
val cm: Config = ConfigFactory.parseMap(mapAsJavaMap(m)).resolve
val cf: Config = ConfigFactory.parseFile(f).resolve

println("b from string = " + cs.getString("b"))
println("b from map = " + cm.getString("b"))
println("b from file = " + cf.getString("b"))

> b from string = another test
> b from map = another ${a}
> b from file = another ${a}

当我没有立即解析时,可以看出变量占位符的处理方式并不相同:

val cs: Config = ConfigFactory.parseString(s)
val cm: Config = ConfigFactory.parseMap(mapAsJavaMap(m))
val cf: Config = ConfigFactory.parseFile(f)

> cs: com.typesafe.config.Config = Config(SimpleConfigObject({"a":"test","b":"another "${a}}))
> cm: com.typesafe.config.Config = Config(SimpleConfigObject({"a":"test","b":"another ${a}"}))
> cf: com.typesafe.config.Config = Config(SimpleConfigObject({"a":"test","b":"another ${a}"}))

我也许可以将 map/file 转换为字符串,但有没有办法让库处理它?

ConfigFactory.parseMap方法导致fromAnyRef,与我们相关的部分是:

if (object instanceof String)
  return new ConfigString.Quoted(origin, (String) object);

它从不将值解析为 ConfigReference,因此 resolve 无法工作。

他们的理由可能是,如果您 "control" 数据结构,那么您可以以某种方式利用 Scala 字符串插值。


对于 parseFile 情况更容易。 Java 属性文件不支持 ${} 替换,文件类型由 (.properties) 文件扩展名猜测。

例如,您可以只使用 HOCON 格式:您只需重命名文件(例如 test.conf),然后 ${} 替换应该可以解决 -盒子。

这里有更多信息:HOCON