我想拦截类的所有方法(实例和静态),甚至是丢失的方法。
这么说吧:
class SomeClass {
def methodMissing(String name, args) {
if(name == "unknownMethod"){
return "result from unknownMethod"
}
else throw new MissingMethodException(name, delegate, args)
}
}
SomeClass.metaClass.static.invokeMethod = { methodName, args ->
println "Before"
def result = delegate.metaClass.invokeMethod(delegate, methodName, *args)
println "After"
return result
}
new SomeClass().with{ sc ->
sc.unknownMethod() //throw the MissingMethodExcept
}
这对于类实现的方法效果很好,但是当它是由 methodMissing 处理的方法时,我会得到一个 MissingMethodException...
你会怎么做?
提前致谢
最佳答案
我认为您还需要捕获非静态invokeMethod
此外,您需要通过 getMetaMethod
来调用原始方法,否则会有堆栈溢出的风险。
鉴于以下情况:
class SomeClass {
String name
static String joinWithCommas( a, b, c ) {
[ a, b, c ].join( ',' )
}
String joinAfterName( a, b, c ) {
"$name : ${SomeClass.joinWithCommas( a, b, c )}"
}
def methodMissing(String name, args) {
if(name == "unknownMethod"){
return "result from unknownMethod"
}
else {
throw new MissingMethodException( name, SomeClass, args )
}
}
}
// Return a closure for invoke handler for a class
// with a given title (for the logging)
def invokeHandler = { clazz, title ->
{ String methodName, args ->
println "Before $methodName ($title)"
def method = clazz.metaClass.getMetaMethod( methodName, args )
def result = method == null ?
clazz.metaClass.invokeMissingMethod( delegate, methodName, args ) :
method.invoke( delegate, args )
println "After $methodName result = $result"
result
}
}
SomeClass.metaClass.invokeMethod = invokeHandler( SomeClass, 'instance' )
SomeClass.metaClass.static.invokeMethod = invokeHandler( SomeClass, 'static' )
new SomeClass( name:'tim' ).with { sc ->
sc.joinAfterName( 'a', 'b', 'c' )
sc.unknownMethod( 'woo', 'yay' )
sc.cheese( 'balls' )
}
我得到输出:
Before with (instance)
Before joinAfterName (instance)
Before joinWithCommas (static)
After joinWithCommas result = a,b,c
After joinAfterName result = tim : a,b,c
Before unknownMethod (instance)
After unknownMethod result = result from unknownMethod
Before cheese (instance)
Exception thrown
groovy.lang.MissingMethodException: No signature of method: SomeClass.cheese() is applicable for argument types: (java.lang.String) values: [balls]
关于Groovy MetaProgramming - 拦截所有方法,甚至丢失的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15898371/