Typesafe Config中Config.withValue更新后变量替换未重新计算问题
问题:使用
Config.withValue更新配置后,变量替换未重新生效 我来帮你解决这个Typesafe Config的问题——你遇到的情况是,当用withValue更新配置项后,调用resolve()并没有让依赖该项的占位符(比如zooKeeperAddr2依赖zooKeeperAddr)重新计算,导致依赖项还是初始值。
你的示例重现
首先是你的application.conf配置文件:
zooKeeperAddr = "localhost:2181" zooKeeperAddr2 = ${zooKeeperAddr}
然后是你的应用代码:
val config = ConfigFactory.load() .withValue("zooKeeperAddr", ConfigValueFactory.fromAnyRef("abc")) .resolve; val zooKeeperAddr = config.getAnyRef("zooKeeperAddr") val zooKeeperAddr2 = config.getAnyRef("zooKeeperAddr2") println(s"zooKeeperAddr, zooKeeperAddr2 is $zooKeeperAddr, $zooKeeperAddr2")
运行这段代码后,你会发现zooKeeperAddr确实变成了abc,但zooKeeperAddr2仍然是localhost:2181,和预期不符。
问题原因
这是因为默认的resolve()方法只会在初始加载配置时解析占位符。当你用withValue修改单个配置项后,它只是替换了该节点的值,并没有触发整个配置树的重新解析,所以依赖该节点的占位符依然保留着初始解析的结果。
解决方案
要让依赖的占位符重新计算,你需要重新触发整个配置树的解析流程,这里有两种可靠的方式:
方案1:将修改后的配置重新解析为新的Config对象
把修改后的配置转换为HOCON字符串,再重新加载并解析,这样所有占位符都会基于最新的值重新计算:
// 加载原始配置 val originalConfig = ConfigFactory.load() // 修改目标配置项 val updatedConfig = originalConfig.withValue("zooKeeperAddr", ConfigValueFactory.fromAnyRef("abc")) // 将修改后的配置转为HOCON字符串,重新解析并resolve val resolvedConfig = ConfigFactory.parseString(updatedConfig.root().render()).resolve() val zooKeeperAddr = resolvedConfig.getAnyRef("zooKeeperAddr") val zooKeeperAddr2 = resolvedConfig.getAnyRef("zooKeeperAddr2") println(s"zooKeeperAddr, zooKeeperAddr2 is $zooKeeperAddr, $zooKeeperAddr2")
方案2:使用resolveWith指定解析上下文
利用resolveWith方法,将修改后的配置作为解析的基础上下文,让占位符使用最新的值:
val originalConfig = ConfigFactory.load() val updatedConfig = originalConfig.withValue("zooKeeperAddr", ConfigValueFactory.fromAnyRef("abc")) // 用更新后的配置作为解析上下文,重新解析原始配置 val resolvedConfig = originalConfig.resolveWith(updatedConfig) val zooKeeperAddr = resolvedConfig.getAnyRef("zooKeeperAddr") val zooKeeperAddr2 = resolvedConfig.getAnyRef("zooKeeperAddr2") println(s"zooKeeperAddr, zooKeeperAddr2 is $zooKeeperAddr, $zooKeeperAddr2")
这两种方式都能让zooKeeperAddr2正确更新为abc,解决你的问题。
内容的提问来源于stack exchange,提问作者tpdi
相关产品推荐
相关产品推荐

