如何使用java方法?

时间:2012-05-18 20:54:30

标签: java instrumentation

我想编写一个简单的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 !

感谢您的帮助!

5 个答案:

答案 0 :(得分: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.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial2.html#intro

答案 1 :(得分:4)

我似乎记得AspectJ可以做到这样的事情;但是,我没有经验,所以探索可能性取决于你! :d

答案 2 :(得分: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();
}

我不确定这是不是你想要的。

答案 3 :(得分:1)

我认为这不容易。

我能想到的唯一选择是实现一个类加载器并用你创建的存根替换原始类(Hibernate / JPA为延迟加载做了类似的事情)。存根将执行您需要的操作,然后调用原始类来执行工作。这将意味着沉重的负担(反思电话并不便宜)。

答案 4 :(得分:0)

如果您只需要记录调用或不调用的方法,那么面向方面的编程就是您所需要的,无论是AspectJ(静态)还是Spring AOP(动态),都能提供强大的功能。 但是,如果您想要执行更多仪器操作,可能需要一些仪器库,例如跟踪执行时间,调用轨道。 希望它有所帮助。