Как я могу перехватить выполнение всех методов в приложении Java, используя Groovy? - PullRequest
5 голосов
/ 04 августа 2009

Можно ли перехватить все методы, вызываемые в приложении? Я хотел бы сделать что-то с ними, а затем позволить им выполнить. Я попытался изменить это поведение в Object.metaClass.invokeMethod, но, похоже, оно не работает.

Это выполнимо?

Ответы [ 2 ]

2 голосов
/ 07 августа 2009

Вы смотрели на Groovy AOP ? Существует очень мало документации , но она позволяет вам определять баллы и рекомендации концептуально аналогично AspectJ. Взгляните на модульные тесты , чтобы найти еще несколько примеров

В приведенном ниже примере будут сопоставлены все вызовы ко всем типам тканых тканей и будут применяться рекомендации перед продолжением:

// aspect MyAspect
class MyAspect {
  static aspect = {
    //match all calls to all calls to all types in all packages
    def pc = pcall("*.*.*")

    //apply around advice to the matched calls
    around(pc) { ctx ->
      println ctx.args[0]
      println ctx.args.length
      return proceed(ctx.args)
    }
  }
}
// class T
class T {
  def test() {
    println "hello"
  }
}
// Script starts here
weave MyAspect.class
new T().test()
unweave MyAspect.class
1 голос
/ 11 августа 2009

Прежде всего, переопределение Object.metaClass.invokeMethod не работает, потому что, когда Groovy пытается разрешить вызов метода для типа X, он проверяет метакласс X, но не метакласс своего родительского класса (классов). Например, следующий код напечатает «метод intValue intercepted»

Integer.metaClass.invokeMethod = {def name, def args ->
  System.out.println("method $name intercepted")
}

6.intValue()

// Reset the metaClass  
Integer.metaClass = null  

Но этот код не будет:

Object.metaClass.invokeMethod = {def name, def args ->
  System.out.println("method $name intercepted")
}

6.intValue()

// Reset the metaClass  
Object.metaClass = null

Ваш вопрос был «Возможно ли перехватить все методы, вызываемые в приложении?», Но не могли бы вы быть более точным в том, хотите ли вы:

  • Перехват вызовов Groovy, Java-методов или обоих методов
  • перехватывать вызовы только ваших методов Groovy / Java или также перехватывать вызовы классов библиотеки Groovy / Java

Например, если вы хотите только перехватывать вызовы ваших классов Groovy, вы можете изменить свои классы для реализации GroovyInterceptable . Это гарантирует, что invokeMethod () вызывается для каждого метода, вызываемого в этих классах. Если характер перехвата (т.е. то, что вы хотите сделать до / после вызова вызываемого метода) одинаков для всех классов, вы можете определить invokeMethod() в отдельном классе и использовать @Mixin, чтобы применить его ко всем вашим классам. классы.

В качестве альтернативы, если вы также хотите перехватывать вызовы к классам Java, вы должны проверить DelegatingMetaClass .

...