Something like below will do? Using invokeMethod
to intercept calls to each method. Test is self explanatory.
Explanation:
Below metaClass implementation overrides invokeMethod from GroovyObject
. Since all groovy objects inherit from GroovyObject, we gain the flexibility of manipulating/intercepting method calls or even specify our own methodMissing
implementation. We would need one override for static and one for non-static methods. Basically, invokeMethod intercepts calls to each method on the Class on which it is defined. We end up with some before
and after
functionalities for each method. Using reflection the below implementation is able to find out the method by its name and argument and invoke it in runtime.
Note:-
- Make sure the returned value from the method call is returned from the closure as well
- Might be a expensive of a class has number of methods with heavy implementation
- If selective execution is required, then check for the method name and then intercept the call
Implementation:
class Dummy {
def method1() { System.out.println "In method 1" }
def method2(String str) { System.out.println "In method 2" }
static def method3(int a, int b) {
System.out.println "In static method 3"
}
}
Dummy.metaClass.invokeMethod = {String name, args ->
def result
System.out.println(
"Do something before $name is called with args $args")
try {
result = delegate.metaClass.getMetaMethod(name, args)
.invoke(delegate, args)
} catch(Exception e) {
System.out.println "Handling exception for method $name"
}
System.out.println(
"Do something after $name was called with args $args \n")
result
}
Dummy.metaClass.'static'.invokeMethod = {String name, args ->
def result
System.out.println(
"Do something before static method $name is called with args $args")
try {
result = delegate.metaClass.getMetaMethod(name, args)
.invoke(delegate, args)
} catch(Exception e) {
System.out.println "Handling exception for method $name"
}
System.out.println(
"Do something after static method $name was called with args $args \n")
result
}
def dummy = new Dummy()
dummy.method1()
dummy.method2('Test')
Dummy.method3(1, 2)