我有一个应用程序,其中一些配置存储在数据库中,并在启动时将它们注入到配置对象中。它们的存储方式是object path
字符串,例如:"some.config.value"
.
所以解析后就变成了这样的map:
[some: [config: [value: [:]]]]
我使用 实现了这一点Binding
,这是代码:
Binding bind = new Binding()
bind.tmp = bean // Bean is an object where it is being injected
String[] traverse = stringPath.split(/\./)
def shift = bind.tmp
traverse.eachWithIndex { String it, int i ->
if (it) {
if (!(shift instanceof Map)) {
shift = ["$it": [:]] // <-- Doesn't work
} else {
if (!shift?.containsKey(it)) {
// val - is a value to assign to last key in path
shift[it] = (i + 1 == traverse.size()) ? val : [:]
} else if (shift?.containsKey(it) && (i + 1 == traverse.size())) {
shift[it] = val
}
}
shift = shift[it]
}
}
这种方法的问题在于,如果我已经在绑定中定义了键,我似乎无法重新定义它(在 中shift = ["$it": [:]]
)。
例如:如果我有config.val
并且config.val.moreConfig
- 则moreConfig
不会被分配。
一段时间后,我决定通过value
自动在所有路径中声明键来分配值,但我仍然很好奇是否有办法在绑定中重新定义值?
还是Binding
在 groovy 中声明的值变得可变?
更新:
bean
是一个带有硬编码配置的哈希映射。它可能只是一张空地图。基本上我正在做的是在最后注入更多有价值的地图。
如果我有一个价值链:
"config.some.var" = 10
"config.some.var2" = 20
"config.some.var.more" = 30
将导致:
[config: [
some: [
var: 10,
var2: 20
]
]]
最新的预期将被丢弃,因为它的值已经为10
. 我想要的是用最新的覆盖第一个值,同时将所有其他值保留在同一深度。
上面的代码产生以下内容:
def bean = [someOtherConfig: []]
convert bean, 'config.var', 10
convert bean, 'config.var2', 20
convert bean, 'config.var.more', 30
assert bean == [someOtherConfig: [], config: [var: 10, var2: 20]]