我怎么可以拦截在使用Groovy Java应用程序的所有方法执行?(How can I interc

2019-09-22 03:08发布

是否有可能拦截所有的调用一个应用程序的方法呢? 我希望做一些与他们,然后让他们执行。 我试图覆盖这种行为Object.metaClass.invokeMethod ,但它似乎并没有工作。

这是可行的?

Answer 1:

你看着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


Answer 2:

首先,覆盖Object.metaClass.invokeMethod不起作用,因为在Groovy中尝试解析方法调用一个X型,它会检查X的元类,而不是它的父类(ES)的元类。 例如,下面的代码将打印“方法的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

你的问题是“是否有可能拦截所有的应用程序调用的方法?”,但你可能会多一点精确您是否想:

  • 拦截来电常规方法,Java方法,或两者
  • 拦截来电只有你的 Groovy / Java方法或还拦截调用的Groovy / Java类库

例如,如果你只是想拦截你的Groovy类来电,你可以改变你的类来实现GroovyInterceptable 。 这确保了的InvokeMethod()被调用用于每个呼吁这些类方法。 如果截取的性质(即你要调用所调用的方法后/前做的东西)是相同的所有类,你可以定义invokeMethod()在一个单独的类,并使用@Mixin将它应用到所有的类。

另外,如果你也想拦截Java类调用,你应该看看DelegatingMetaClass 。



文章来源: How can I intercept execution of all the methods in a Java application using Groovy?