Comment puis-je intercepter l'exécution de toutes les méthodes d'une application Java à l'aide de Groovy?
-
22-07-2019 - |
Question
Est-il possible d'intercepter toutes les méthodes appelées dans une application? J'aimerais faire quelque chose avec eux, puis les laisser exécuter. J'ai essayé de remplacer ce comportement dans Object.metaClass.invokeMethod
, mais cela ne semble pas fonctionner.
Est-ce faisable?
La solution
Avez-vous consulté Groovy AOP ? Il y a très peu de documentation, mais elle permet vous définissez des points de coupe et des conseils d’une manière conceptuellement semblable à celle d’AspectJ. Jetez un coup d'œil au tests unitaires pour quelques exemples supplémentaires
L'exemple ci-dessous correspond à tous les appels de tous les types de tissus et applique le conseil avant de poursuivre:
// 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
Autres conseils
Tout d’abord, remplacer Object.metaClass.invokeMethod
ne fonctionne pas car, lorsque Groovy essaie de résoudre un appel de méthode pour un type X, il vérifie la métaClass de X, mais pas la métaClass de. sa classe parent (es). Par exemple, le code suivant affichera "méthode intValue de la méthode interceptée"
Integer.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Integer.metaClass = null
Mais ce code ne sera pas:
Object.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Object.metaClass = null
Votre question était "Est-il possible d'intercepter toutes les méthodes appelées dans une application?", mais pourriez-vous préciser un peu plus si vous souhaitez:
- Interception des appels vers les méthodes Groovy, les méthodes Java ou les deux
- Intercepter les appels uniquement vers vos méthodes Groovy / Java ou également intercepter les appels vers les classes de bibliothèque Groovy / Java
Par exemple, si vous souhaitez uniquement intercepter les appels de vos classes Groovy, vous pouvez modifier vos classes pour implémenter GroovyInterceptable . Cela garantit que invokeMethod () est appelé pour chaque méthode appelée sur ces classes. Si la nature de l'interception (c'est-à-dire ce que vous voulez faire avant / après l'appel de la méthode appelée) est identique pour toutes les classes, vous pouvez définir invokeMethod ()
dans une classe distincte et utiliser @Mixin
pour l'appliquer à toutes vos classes.
Si vous souhaitez également intercepter les appels vers les classes Java, vous devez également consulter la DelegatingMetaClass .