Groovyを使用してJavaアプリケーションのすべてのメソッドの実行をインターセプトするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1226821

質問

アプリケーションで呼び出されるすべてのメソッドをインターセプトすることは可能ですか?私は彼らと一緒に何かをして、それから彼らに実行させたいです。 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のmetaClassがチェックされますが、その親クラス。たとえば、次のコードは" 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メソッド、Javaメソッド、またはその両方の呼び出しをインターセプトする
  • Groovy / Javaメソッドのみへの呼び出しをインターセプトするか、Groovy / Javaライブラリクラスへの呼び出しをインターセプトします

たとえば、Groovyクラスへの呼び出しのみをインターセプトする場合は、クラスを変更して GroovyInterceptable 。これにより、それらのクラスで呼び出されるすべてのメソッドに対してinvokeMethod()が呼び出されます。インターセプトの性質(つまり、呼び出されたメソッドの呼び出しの前後に行うこと)がすべてのクラスで同じ場合、別のクラスで invokeMethod()を定義し、 @Mixin を使用して、すべてのクラスに適用します。

また、Javaクラスへの呼び出しもインターセプトしたい場合は、 DelegatingMetaClass

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top