我正在尝试使用Groovy的Meta Programming从关闭动态读取数据。下面是示例:
class MyClass {
static def metadata1 = {
metadataA(key1: 'value1', key2: "value2")
metadataB(key1: ['value1', 'value2'], key2: 78978)
}
static def metadata2 = {
metadataA(key1: 'value11', key2: "value21")
metadataB(key1: ['value11', 'value21'], key2: 78958)
}
static void main(def args) {
new MyClass().setup("metadata1")
new MyClass().setup("metadata2")
}
def setup(fieldName) {
try {
Field metaField = this.class.getDeclaredField(fieldName)
if (metaField != null) {
metaField.setAccessible(true)
def metaFieldVal = metaField.get(null)
if (metaFieldVal != null) {
metaFieldVal.delegate = this
metaFieldVal() // It will call closure metadata1 or metadata2
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace()
}
}
def methodMissing(String key, args) {
println(key) // metadataA
println(args) // [[key1:value1, key2:value2]]
//println(getNameofCalleeClosure()) //metadata1
}
}
在重写的方法中,我无法识别被调用方关闭的字段名称,在这种情况下,即元数据1,元数据2。在Groovy中,有什么方法可以从调用位置获取被调用方关闭名称以进行标识?
答案 0 :(得分:1)
没有诸如调用方关闭名称之类的东西。在您的示例中,在方法setup(fieldName)
中搜索一个存储为类字段的闭包,找到闭包后,您将使用metaFieldVal()
执行该闭包。字段名称metadata1
与以metaFieldVal()
执行的闭包之间没有连接。实际上,setup(fieldName)
知道此闭包存储为类字段,但是闭包本身并不知道它。
如果要在metadata1
内获取metadata2
或methodMissing()
字段名称,则只需将其作为此不存在的方法参数传递即可。像这样:
class MyClass {
static def metadata1 = {
metadataA("metadata1", [key1: 'value1', key2: "value2"])
metadataB("metadata1", [key1: ['value1', 'value2'], key2: 78978])
}
static def metadata2 = {
metadataA("metadata2", [key1: 'value11', key2: "value21"])
metadataB("metadata2", [key1: ['value11', 'value21'], key2: 78958])
}
static void main(def args) {
new MyClass().setup("metadata1")
new MyClass().setup("metadata2")
}
def setup(fieldName) {
try {
Field metaField = this.class.getDeclaredField(fieldName)
if (metaField != null) {
metaField.setAccessible(true)
def metaFieldVal = metaField.get(null)
if (metaFieldVal != null) {
metaFieldVal.delegate = this
metaFieldVal() // It will call closure metadata1 or metadata2
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace()
}
}
def methodMissing(String key, args) {
println(key) // metadataA
println(args) // [metadata1, [key1:value1, key2:value2]]
}
}
值得一提的是,执行缺少的方法是这样的:
static def metadata1 = {
metadataA(this, [key1: 'value1', key2: "value2"])
metadataB(this, [key1: ['value1', 'value2'], key2: 78978])
}
产生:
[class MyClass, [key1:value1, key2:value2]]
并像这样传递字段metadata1
:
static def metadata1 = {
metadataA(metadata1, [key1: 'value1', key2: "value2"])
metadataB(metadata1, [key1: ['value1', 'value2'], key2: 78978])
}
将产生:
[MyClass$__clinit__closure1@50d0686, [key1:value1, key2:value2]]
因为闭包没有名字。