Как я могу перехватить выполнение всех методов в Java-приложении с помощью Groovy?

StackOverflow https://stackoverflow.com/questions/1226821

Вопрос

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

Выполнимо ли это?

Это было полезно?

Решение

Вы просматривали Groovy AOP ? Существует очень мало документации , но это позволяет, Вы должны определить pointcuts и совет концептуально аналогично 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

Другие советы

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

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, вы могли бы изменить свои классы на implementate Желобчатый, незаметный.Это гарантирует, что invokeMethod() вызывается для каждого метода, вызываемого в этих классах.Если характер перехвата (т. е.то, что вы хотите сделать до / после вызова вызываемого метода) одинаково для всех классов, вы могли бы определить invokeMethod() в отдельный класс и использовать @Mixin чтобы применить это ко всем вашим занятиям.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top