如何使用 Groovy 拦截 Java 应用程序中所有方法的执行?
-
22-07-2019 - |
题
是否可以拦截应用程序中调用的所有方法?我想和他们一起做一些事情,然后让他们执行。我试图覆盖这种行为 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拦截”
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 方法、Java 方法或两者的调用
- 仅拦截呼叫 你的 Groovy/Java 方法或拦截对 Groovy/Java 库类的调用
例如,如果您只想拦截对 Groovy 类的调用,您可以更改您的类以实现 GroovyInterceptable. 。这可确保为这些类上调用的每个方法调用 invokeMethod()。如果拦截的性质(即您想要在调用被调用方法之前/之后执行的操作)对于所有类都是相同的,您可以定义 invokeMethod()
在一个单独的类中并使用 @Mixin
将其应用到您的所有课程中。
或者,如果您还想拦截对 Java 类的调用,您应该查看 委托元类.
不隶属于 StackOverflow