在类型安全配置中加载时禁止解析

Prohibit resolving during loading in typesafe config

我想禁止解析 a.b。我想用另一个配置替换 param。像这样:

val d = ConfigFactory.load(ConfigFactory.parseString(
    """
      |param = x
      |a.b = ${param}
    """.stripMargin))

val a = ConfigFactory.parseString("param = 1")

val result = a.withFallback(d).resolve()

在这种情况下 param 获得值 1,但 a.b 仍然是 x 我试图在加载配置 d 时设置 ConfigResolveOptions.defaults().setAllowUnresolved(true),但这不起作用。

我该如何克服这个问题?

我在同一件事上遇到了一些困难:尝试使用 "fallbacks" 覆盖值,而它是为 layering/merging 配置

设计的

假设我了解您的用例,我建议改用文件包含。

在我的application.conf中我有默认值

a.b = "placeholder"

在底部我有以下内容

# Local overrides - for development use
include "local.conf"

最后在 local.conf

param = 1
a.b = ${param}

最终结果是 a.b 将被 1

覆盖

问题是 Config.load 正在立即解析替换。如果你把它去掉,它就会像你想要的那样解析:

val p = ConfigFactory.parseString(
  """
    |param = x
    |a.b = ${param}
  """.stripMargin)

val a = ConfigFactory.parseString("param = 1")

val result = a.withFallback(p).resolve()

println(result.getString("a.b"))

这会打印 1。

你不需要使用Config.load,除非你想使用reference.conf,等等。如果你确实想使用Config.load,那么你应该在你写完之后再做所有配置一起使用 withFallback

例如,这也会打印 1:

  val p = ConfigFactory.parseString(
    """
      |param = x
      |a.b = ${param}
    """.stripMargin)

  val d = ConfigFactory.load(p)
  val a = ConfigFactory.parseString("param = 1")

  val result = a.withFallback(p)
  val loaded = ConfigFactory.load(result)
  println(loaded.getString("a.b"))

或者,假设您有一个 application.confinclude,您希望将其与 ConfigFactory.load() 一起使用(根据您的评论)。

如果application.conf看起来像

include "foo"

foo.conf看起来像

a.b = ${param}

然后这也打印 1:

  val a = ConfigFactory.parseString("param = 1")  

  val app = ConfigFactory.load("application", ConfigParseOptions.defaults,
    ConfigResolveOptions.defaults.setAllowUnresolved(true))

  val result = a.withFallback(app).resolve

  println(result.getString("a.b"))

一般来说,如果你想让A覆盖B覆盖C那么你应该使用A.withFallback(B).withFallback(C).

找到解决我的问题的方法:

因此,如果我有配置文件 application.conf,它使用 include 来包含包含替换语法的配置文件和包含将要替换的配置值声明的文件。

val a = ConfigFactory.parseString(s"""param = 1""")
 val z = ConfigFactory.parseResources("application.conf") //this doesn't resolve substitutions

val result = a.withFallback(z).resolve().withFallback(ConfigFactory.load("application.conf"))