3

首先看下面的 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)的详细解释,我将不胜感激。

4

1 回答 1

4

简而言之,您没有使用标准的元类,因此您没有获得标准的 Groovy MOP。

Car.metaClass.invokeMethod = {将让 Car 有一个 ExpandoMetaClass 作为元类。这个元类使用你作为开放块(就像你做的那样)提供的 invokeMethod 来拦截调用。这与在类本身中定义一个 invokeMethod 非常不同。

于 2015-06-15T05:45:37.417 回答