对 Groovy MOP 中的 invokeMethod 方法感到困惑
Confused about the invokeMethod method in the Groovy MOP
先看下面Groovy代码:
class Car {
def check() { System.out.println "check called..." }
def start() { System.out.println "start called..." }
}
Car.metaClass.invokeMethod = { String name, args ->
System.out.print("Call to $name intercepted... ")
if (name != 'check') {
System.out.print("running filter... ")
Car.metaClass.getMetaMethod('check').invoke(delegate, null)
}
def validMethod = Car.metaClass.getMetaMethod(name, args)
if (validMethod != null) {
validMethod.invoke(delegate, args)
} else {
Car.metaClass.invokeMissingMethod(delegate, name, args)
}
}
car = new Car()
car.start()
输出为:
Call to start intercepted... running filter... check called...
start called...
根据Groovy的方法调度机制我觉得应该直接调用Car中的start方法,而不是被Car的metaClass中的invokeMethod拦截。为什么start方法会被invokeMethod拦截?在对象上调用方法时如何调用invokeMethod?
如果你能给我一些关于Groovy方法调度机制(MOP)的详细解释,我将不胜感激。
简而言之,您没有使用标准元 class,因此您没有获得标准 Groovy MOP。
Car.metaClass.invokeMethod = {
会让 Car 有一个 ExpandoMetaClass 作为元 class。此元 class 使用您提供的 invokeMethod 作为 open 块(就像您所做的那样)来拦截调用。这与在 class 本身中定义 invokeMethod 非常不同。
先看下面Groovy代码:
class Car {
def check() { System.out.println "check called..." }
def start() { System.out.println "start called..." }
}
Car.metaClass.invokeMethod = { String name, args ->
System.out.print("Call to $name intercepted... ")
if (name != 'check') {
System.out.print("running filter... ")
Car.metaClass.getMetaMethod('check').invoke(delegate, null)
}
def validMethod = Car.metaClass.getMetaMethod(name, args)
if (validMethod != null) {
validMethod.invoke(delegate, args)
} else {
Car.metaClass.invokeMissingMethod(delegate, name, args)
}
}
car = new Car()
car.start()
输出为:
Call to start intercepted... running filter... check called...
start called...
根据Groovy的方法调度机制我觉得应该直接调用Car中的start方法,而不是被Car的metaClass中的invokeMethod拦截。为什么start方法会被invokeMethod拦截?在对象上调用方法时如何调用invokeMethod?
如果你能给我一些关于Groovy方法调度机制(MOP)的详细解释,我将不胜感激。
简而言之,您没有使用标准元 class,因此您没有获得标准 Groovy MOP。
Car.metaClass.invokeMethod = {
会让 Car 有一个 ExpandoMetaClass 作为元 class。此元 class 使用您提供的 invokeMethod 作为 open 块(就像您所做的那样)来拦截调用。这与在 class 本身中定义 invokeMethod 非常不同。