Перехват вызовов к свойствам - PullRequest
0 голосов
/ 23 октября 2009

Я пытаюсь перехватить все вызовы свойств в классе Groovy. Поскольку это не сработало, как ожидалось, я создал следующий пример:

class TestClass {
    def getProperty(String key) {
        println "getting property: " + key
    }

    def invokeMethod(String method, args) {
        println "invoking method: " + method
    }

    def getFoo() {
        return 1
    }
}
tc.foo      // 1
tc.getFoo() // 2

1) поступает правильно, то есть вызывается getProperty. Тем не менее, 2) работает (т.е. возвращается 1), но не вызывается ни getProperty, ни invokeMethod.

Есть ли способ перехватить вызов getfoo ()?

Stefan

Ответы [ 3 ]

0 голосов
/ 30 октября 2009

Мне пришлось немного изменить код в предыдущем ответе, чтобы получить то, что, я думаю, вы хотите:

TestClass.metaClass.invokeMethod = {method, args ->
  def metaMethod = TestClass.metaClass.getMetaMethod(method,args)
  println "executing $method with args $args on $delegate"
  metaMethod.invoke(delegate,args) // could result in NPE
}

Затем выполняется

tc.foo
tc.getFoo()

Результат:

getting property: foo                               // println output
null                                                // getProperty return is null
executing getFoo with args [] on TestClass@655538e5 // invokeMethod output
1                                                   // metaMethod invocation
0 голосов
/ 24 октября 2011

Проблема заключается в том, что здесь используется два разных типа путей обработки запроса. Для запроса свойств метод getProperty вызывается до того, как мы перейдем к мета-классу - если вы перезаписываете getProperty, вы должны сделать вызов мета-класса самостоятельно. В случае invokeMethod обычно запрашивается после мета-класса. Так как мета-класс будет отвечать на ваш запрос getFoo (), invokeMethod вообще не будет запрашиваться. Если вы позволите классу реализовать GroovyInterceptable, то сначала будет вызываться invokeMethod, так же, как getProperty. Это также объясняет, почему способы использования мета-класса работают.

0 голосов
/ 23 октября 2009

Я написал статью пару месяцев назад. Вы можете прочитать это здесь .

Попробуйте этот код:

TestClass.metaClass.invokeMethod = {
   def metaMethod = delegate.metaClass.getMetaMethod(method,args)
   println "executing $method with args $args on $delegate"
   return metaMethod.invoke(delegate,args)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...