是否可以拦截应用程序中调用的所有方法?我想对他们做点什么,然后让他们执行。我试图在 中覆盖此行为Object.metaClass.invokeMethod
,但它似乎不起作用。
这是可行的吗?
是否可以拦截应用程序中调用的所有方法?我想对他们做点什么,然后让他们执行。我试图在 中覆盖此行为Object.metaClass.invokeMethod
,但它似乎不起作用。
这是可行的吗?
你看过Groovy AOP吗?文档很少,但它允许您以与 AspectJ 类似的概念方式定义切入点和建议。查看单元测试以获取更多示例
下面的示例将匹配对所有编织类型的所有调用,并在继续之前应用建议:
// 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
首先,覆盖Object.metaClass.invokeMethod
不起作用,因为当 Groovy 尝试解析类型 X 的方法调用时,它会检查 X 的元类,而不是其父类的元类。例如下面的代码会打印“method intValue intercepted”
Integer.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Integer.metaClass = null
但是这段代码不会:
Object.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Object.metaClass = null
您的问题是“是否可以拦截应用程序中调用的所有方法?”,但您能否更准确地了解您是否想要:
例如,如果您只想拦截对 Groovy 类的调用,则可以更改您的类以实现GroovyInterceptable。这确保为这些类上调用的每个方法调用 invokeMethod()。如果拦截的性质(即在调用被调用方法之前/之后您想要做的事情)对于所有类都是相同的,那么您可以invokeMethod()
在单独的类中定义并将@Mixin
其应用于所有类。
或者,如果您还想拦截对 Java 类的调用,则应查看DelegatingMetaClass。