6

インストルメントされたJavaプログラムによって呼び出されたメソッドの名前を出力できる単純なJavaエージェントを作成したいと思います。

たとえば、インストルメントしたいJavaプログラムは次のとおりです。

public class TestInstr {

public static void sayHello() {
    System.out.println("Hello !");
}

public static void main(String args[]) {
    sayHello();
    sayHello();
    sayHello();
 }

}

私はこのようなものを表示したいと思います:

method sayHello has been called
Hello !
method sayHello has been called
Hello !
method sayHello has been called
Hello !

ご協力いただきありがとうございます!

4

5 に答える 5

11

Javassistなどのインストルメンテーションライブラリを使用してこれを行うことができます。

単一のメソッドの例を挙げましょう。これは、Javassistまたはリフレクションを使用してすべてのメソッドに拡張できます。

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("TestInstr");
CtMethod m = cc.getDeclaredMethod("sayHello");
m.insertBefore("{ System.out.println(\"method sayHello has been called\"); }");
cc.writeFile();

詳細はこちらのリンクをご確認ください:http ://www.csg.ci.iu-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

于 2012-05-18T21:04:50.257 に答える
4

AspectJ私はそれがこのようなことをすることができることを覚えているようです。しかし、私はそれを経験したことがないので、可能性を探求するのはあなた次第です!:D

于 2012-05-18T20:58:37.107 に答える
1

メソッドに追加できます

public class TestInstr {

public static void sayHello() {
System.out.println("method sayHello has been called");
System.out.println("Hello !");
}

public static void main(String args[]) {
sayHello();
sayHello();
sayHello();
}
}

これを使用して、現在のメソッドを取得できます

public String getCurrentMethodName() {
 StackTraceElement stackTraceElements[] =
         (new Throwable()).getStackTrace();
 return stackTraceElements[1].toString();
}

これがあなたが探しているものかどうかはわかりません。

于 2012-05-18T20:58:11.123 に答える
1

簡単ではないと思います。

私が考えることができる唯一のオプションは、クラスローダーを実装し、元のクラスを自分で作成したスタブに置き換えることです(Hibernate / JPAは遅延読み込みに対してそのようなことを行います)。スタブは必要な操作を実行してから、元のクラスを呼び出して作業を実行します。それは重い負担を意味します(リフレクションコールは安くはありません)。

于 2012-05-18T20:59:06.863 に答える
0

メソッドが呼び出されたかどうかを単に記録する必要がある場合は、アスペクト指向プログラミングは、AspectJ(静的)またはSpring AOP(動的)に関係なく、必要なものとまったく同じです。どちらもそれを行うための強力な機能を提供します。ただし、実行時間の追跡、トラックの呼び出しなど、より多くのインストゥルメント処理を実行する場合は、いくつかのインストゥルメントライブラリが必要になる場合があります。それが役に立てば幸い。

于 2014-10-22T04:02:32.810 に答える