【问题标题】:Resolve one Typesafe Config object with other用另一个解析一个 Typesafe Config 对象
【发布时间】:2013-06-20 22:42:53
【问题描述】:

我想解决一个Config 对象,比如config1 和其他对象,比如config2。

唯一允许此类操作的公共 API 是 config1.withFallback(config2).resolve()。但是,这会将 config2 的条目添加到 config1,这不是我们想要的。

在一些调查中,我们发现了一个名为ResolveContext 的非公共类,它为此提供了一个方法。所以我们使用反射来利用它。我们当前的代码:

object ConfigImplicits {
  implicit class RichConfig(val config: Config) extends AnyVal {
    def resolveWith(source: Config): Config = {
      val resolver = resolveContext.getDeclaredMethod(
        "resolve", 
        abstractConfigValue, 
        abstractConfigObject, 
        configResolveOptions
      )
      resolver.setAccessible(true)
      resolver.invoke(
        null,
        config.underlyingAbstractConfigObject,
        source.underlyingAbstractConfigObject,
        ConfigResolveOptions.defaults
      ).asInstanceOf[ConfigObject].toConfig
    }

    def underlyingAbstractConfigObject = {
      val f = simpleConfig.getDeclaredField("object")
      f.setAccessible(true)
      f.get(config)
    }
  }

  val resolveContext = Class forName "com.typesafe.config.impl.ResolveContext"
  val abstractConfigValue = Class forName "com.typesafe.config.impl.AbstractConfigValue"
  val abstractConfigObject = Class forName "com.typesafe.config.impl.AbstractConfigObject"
  val configResolveOptions = classOf[ConfigResolveOptions]
  val simpleConfig = Class forName "com.typesafe.config.impl.SimpleConfig"
}

我们意识到,依赖非公开内部信息可能不是一个好主意。所以:

  1. 是否有一个我们以某种方式遗漏的公共方法已经这样做了?
  2. 如果没有,我们是否应该提出拉取请求?

【问题讨论】:

    标签: scala config typesafe


    【解决方案1】:

    AFAIK 没有公共方法。一个不那么脆弱的解决方法而不是依赖私有 API 可能是首先使用您的源对象作为后备进行解析,然后迭代您从中解析的源对象中的键,然后从目标对象中删除那些不需要的键。

    我想不出不添加 Config.resolveWith() 的理由,但我想知道是否有理由,因为我记得考虑过。也许我只是认为没有人会使用它。

    如果您提出拉取请求,请务必包含测试和文档。我认为拉取请求是合理的,假设它的代码很少(如我所料)。当前的 master 分支对 API 添加开放,将出现在最终的 1.2 版本中。

    【讨论】:

    • 似乎有版主滥用了他的权利,并删除了我上次在这里发布的评论。为了正确继续这种交流,我将重复我发布的内容(根据我的记忆):“谢谢。如果成功,我将分叉并尝试添加该方法并提出拉取请求。”正如所承诺的那样,我尝试了,但是层次结构似乎奇怪地纠缠在一起,我无法添加该方法。 [1/2]
    • 您建议的解决方法对我们不起作用,因为原始配置已经具有这些键。我们不希望它们被替换,这就是为什么我们没有使用withFallback,而是编写了resolveWith(使用反射)。
    • 对于未来的旁观者,现在有一个 resolveWith() API 可用。
    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-31
    • 2015-06-10
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    相关资源
    最近更新 更多