Запутался в методе invokeMethod в 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 должен вызываться напрямую, а не перехватываться invokeMethod в метаклассе Car. Почему метод start перехватывается invokeMethod? Как invokeMethod вызывается, когда метод вызывается для объекта?

Если вы можете дать мне некоторые подробные объяснения о механизме диспетчеризации Groovy, я буду признателен за это.

1 ответ

Решение

Короче говоря, вы не используете стандартный мета-класс, поэтому вы не получите стандартную Groovy MOP.

Car.metaClass.invokeMethod = { позволит Car иметь ExpandoMetaClass в качестве метакласса. Этот мета-класс использует invokeMethod, который вы предоставляете как открытый блок (как вы делаете), для перехвата вызовов. Это очень отличается от определения invokeMethod в самом классе.

Другие вопросы по тегам