Запутался в методе 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 в самом классе.