2009-08-04 16 views

Respuesta

2

¿Has mirado Groovy AOP? Hay muy poco documentation, pero le permite definir puntos de corte y consejos de una manera conceptual similar a la de AspectJ. Echar un vistazo a la unit tests para algunos más ejemplos

El siguiente ejemplo servirá para todos las llamadas a todos los tipos de tejido y aplicar la información antes de proceder:

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

En primer lugar, anulando Object.metaClass.invokeMethod no funciona porque cuando Groovy intenta resolver una llamada a un método para un tipo X, comprueba la metaClass de X, pero no la metaClass de su (s) clase (s) primaria (s). 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 Groovy métodos, los métodos de Java, o ambos
  • interceptar llamadas a sólo sus métodos Groovy/Java o también interceptar llamadas a librerías de clases Groovy/Java

Por ejemplo, si sólo desea interceptar llamadas a sus clases Groovy, podría cambiar sus clases para implementar GroovyInterceptable. Esto asegura que se invoca invokeMethod() para cada método llamado en esas clases. Si la naturaleza de la interceptació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 aplicarla a todas sus clases.

Alternativamente, si también desea interceptar llamadas a las clases de Java, debe verificar el DelegatingMetaClass.

+0

Me gustaría poder interceptar las llamadas a métodos Groovy y Java. – Geo

+0

Luego debería usar DelegatingMetaClass o un framework AOP completo como groovy-aop o AspectJ –

+0

No se pueden interceptar llamadas al método * all * con un metaClass, porque los métodos Java llamados desde Java no pasan por el despacho de Groovy. Entonces, si tiene una clase Java llamando a otra clase Java, no puede interceptar esa llamada sin usar algún tipo de AOP o algo así. – noah

Cuestiones relacionadas