Intercepción de Clases Java

Una de las ventajas de utilizar intercepción basada en Metaclases es que puede ser aplicada a clases Java. Veamos un ejemplo:
generaciondecodigos@nereida:~/Lgroovy/mop$ cat -n InterceptingInteger.groovy
     1  Integer.metaClass.invokeMethod = { String name, args ->
     2    println "Call to ${name}() intercepted on $delegate ..."
     3    def validMethod = Integer.metaClass.getMetaMethod(name, args)
     4
     5    println("Running pre-filter ...")
     6      def result = validMethod?.invoke(delegate,args)
     7    println("Running post-filter ...")
     8
     9    result
    10  }
    11
    12  println 5.floatValue()
    13  5.doesNotExists()
La ejecución de este programa produce la siguiente salida:
generaciondecodigos@nereida:~/Lgroovy/mop$ groovy InterceptingInteger.groovy
Call to floatValue() intercepted on 5 ...
Running pre-filter ...
Running post-filter ...
5.0
Call to doesNotExists() intercepted on 5 ...
Running pre-filter ...
Running post-filter ...

El atributo metaClass de la clase Integer es de la clase HandleMetaClass y representa la metaclase asociada con Integer:

groovy:000> Integer.metaClass.getClass().name
===> org.codehaus.groovy.runtime.HandleMetaClass

Esta clase dispone del atributo protected MetaClass delegate y de varios métodos, entre los que está

public MetaMethod getMetaMethod(String name, Object[] args)
It retrieves an instance MetaMethod for the given name and args values, using the types of the argument values to establish the chosen MetaMethod. It returns a MetaMethod or null if it doesn't exist. The class MetaMethod represents a Method on a Java object: a little like Java class Method except without using reflection to invoke the method. CacheMethod.

The MetaMethod object validMethod has a number of methods. Among them

public abstract Object invoke(Object object, Object[] arguments)

Casiano Rodríguez León
2010-04-30