Smalltalk
Вы смотрели Groovy AOP ? Документации очень мало , но она позволяет вам определять pointcut и рекомендации концептуально аналогично 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 , но не метакласс его родительского класса (ов). Например, следующий код напечатает «method 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, вы можете изменить свои классы, чтобы реализовать GroovyInterceptable . Это гарантирует, что invokeMethod () вызывается для каждого метода, вызываемого в этих классах. Если характер перехвата (то есть то, что вы хотите сделать до / после вызова вызываемого метода) одинаков для всех классов, вы можете определить invokeMethod ()
в отдельном классе и использовать @Mixin
, чтобы применить его ко всем вашим классам.
В качестве альтернативы, если вы также хотите перехватывать вызовы классов Java, вы должны проверить DelegatingMetaClass .