Pergunta

É possível interceptar todos os métodos chamados em uma aplicação? Eu gostaria de fazer algo com eles, e depois deixá-los executar. Eu tentei substituir esse comportamento em Object.metaClass.invokeMethod, mas não parece trabalho.

É este factível?

Foi útil?

Solução

Você já olhou para Groovy AOP ? Há muito pouco documentação , mas permite definir pointcuts e conselhos de um modo conceitualmente semelhante como para AspectJ. Ter um olhar para o testes unitários para mais alguns exemplos

O exemplo abaixo irá corresponder a todas as chamadas para todos os tipos de tecidos e aplicar os conselhos antes de prosseguir:

// 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

Outras dicas

Em primeiro lugar, substituindo Object.metaClass.invokeMethod não funciona porque quando Groovy tenta resolver uma chamada de método para um tipo X, ele verifica a metaclasse de X, mas não a metaclasse de sua classe pai (ES). Por exemplo, o seguinte código irá imprimir "método intValue interceptado"

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

6.intValue()

// Reset the metaClass  
Integer.metaClass = null  

Mas este código não vai:

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

6.intValue()

// Reset the metaClass  
Object.metaClass = null

A sua pergunta foi "É possível interceptar todos os métodos chamados em uma aplicação?", Mas você poderia ser um pouco mais preciso sobre se deseja:

  • interceptar chamadas para métodos groovy, métodos Java, ou ambos
  • interceptar chamadas apenas o métodos de Groovy / Java ou também chamadas de interceptar a biblioteca de classes Groovy / Java

Por exemplo, se você quiser apenas para chamadas de interceptação para suas classes Groovy, você pode mudar suas aulas para implementar GroovyInterceptable . Isso garante que invokeMethod () é invocado para cada método chamado nessas classes. Se a natureza da intercepção (ou seja, as coisas que você quer fazer antes / depois de invocar o método chamado) é a mesma para todas as classes, você pode definir invokeMethod() em uma classe e uso @Mixin separado para aplicá-la a todas as suas classes.

Como alternativa, se você também quiser chamadas interceptar a classes Java, você deve verificar se o DelegatingMetaClass .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top