javassist【动态改字节码】学习二



写了个例子。

有一个类:
Java代码

package seeeyou.app.test;

public class HelloWorld {

public static void sayHello(String hh) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("hello world");
}

}



要知道这个方法执行了多久,一般可以直接在sayHello这个方法的前面加
Java代码

    long start = System.currentTimeMillis();

long start = System.currentTimeMillis();

Java代码

    后面加 long end= System.currentTimeMillis()  最后输出下end-start即可

后面加 long end= System.currentTimeMillis()  最后输出下end-start即可



javassist不只是这些功能,还有其他功能。后面再介绍点。

另外一种用javassist的方式也很简单,而且不用在这时改变源代码。

例子如下:
Java代码

package seeeyou.app.test;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;

/**
* 这个例子里用javassist在加载类的时候,给HelloWorld这个类的sayHello方法动态的加入统计方法时间的代码
*
* @author seeeyou
*
*/
public class TestHelloWorld {
public static void main(String[] args) throws NotFoundException,
InstantiationException, IllegalAccessException,
CannotCompileException {
// 用于取得字节码类,必须在当前的classpath中,使用全称
CtClass ctClass = ClassPool.getDefault().getCtClass("seeeyou.app.test.HelloWorld");
// 需要修改的方法名称
String mname = "sayHello";
// 新定义一个方法叫做sayHello$impl
String newMethodName = mname + "$impl";
// 获取这个方法
CtMethod cm = ctClass.getDeclaredMethod(mname);
cm.setName(newMethodName);// 原来的方法改个名字

//创建新的方法,复制原来的方法
CtMethod newMethod = CtNewMethod.copy(cm, mname, ctClass, null);

StringBuilder bodyStr = new StringBuilder();
bodyStr.append("{\nlong start = System.currentTimeMillis();\n");
// 调用原有代码,类似于method();($$)表示所有的参数
bodyStr.append(newMethodName + "($$);\n");

bodyStr.append("System.out.println(\"Call to method " + mname
+ " took \" +\n (System.currentTimeMillis()-start) + "
+ "\" ms.\");\n");

bodyStr.append("}");
// 替换新方法
newMethod.setBody(bodyStr.toString());
// 增加新方法
ctClass.addMethod(newMethod);

// 类已经更改,注意不能使用HelloWorld a=new
// HelloWorld();,因为在同一个classloader中,不允许装载同一个类两次

HelloWorld helloWorld = (HelloWorld) ctClass.toClass().newInstance();
helloWorld.sayHello("add");
}
}



运行结果如下:
Java代码

    hello world
    Call to method sayHello took 3000 ms.

hello world
Call to method sayHello took 3000 ms.



上面这个例子,是可以直接运行的。

javassist不只是这些功能,还有一些其他很好的功能,后面有空再记录下。

你可能感兴趣的:(javassist)