一部の構成がデータベースに保存され、起動時に構成オブジェクトに挿入されるアプリケーションがあります。それらが格納される方法は、次のobject path
ような文字列です"some.config.value"
。
したがって、解析後、次のようなマップになります。
[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
and config.val.moreConfig
- thenを持っていれば、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]]