Pregunta

¿Es posible interceptar todos los métodos llamados en una aplicación? Me gustaría hacer algo con ellos y luego dejar que se ejecuten. Intenté anular este comportamiento en Object.metaClass.invokeMethod , pero parece que no funciona.

¿Es factible?

¿Fue útil?

Solución

¿Has mirado en Groovy AOP ? Hay muy poca documentación , pero permite Defina puntos de corte y consejos de una manera conceptualmente similar a AspectJ. Eche un vistazo a pruebas unitarias para algunos ejemplos más

El siguiente ejemplo coincidirá con todas las llamadas a todos los tipos de tejido y aplicará el consejo antes de continuar:

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

Otros consejos

En primer lugar, reemplazar Object.metaClass.invokeMethod no funciona porque cuando Groovy intenta resolver una llamada de método para un tipo X, comprueba la metaClass de X, pero no la metaClass de sus clases principales. Por ejemplo, el siguiente código 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  

Pero este código no:

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

6.intValue()

// Reset the metaClass  
Object.metaClass = null

Su pregunta fue "¿Es posible interceptar todos los métodos llamados en una aplicación?", pero ¿podría ser un poco más preciso acerca de si desea:

  • Interceptar llamadas a métodos Groovy, métodos Java o ambos
  • Intercepte llamadas solo a sus métodos Groovy / Java o también intercepte llamadas a clases de la biblioteca Groovy / Java

Por ejemplo, si solo desea interceptar llamadas a sus clases Groovy, puede cambiar sus clases para implementar GroovyInterceptable . Esto garantiza que se invoque invokeMethod () para cada método invocado en esas clases. Si la naturaleza de la intercepción (es decir, las cosas que desea hacer antes / después de invocar el método llamado) es la misma para todas las clases, puede definir invokeMethod () en una clase separada y usar @Mixin para aplicarlo a todas tus clases.

Alternativamente, si también desea interceptar llamadas a clases Java, debe consultar DelegatingMetaClass .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top