Comment puis-je intercepter l'exécution de toutes les méthodes d'une application Java à l'aide de Groovy?

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

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?

Était-ce utile?

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 .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top