写了个例子。
有一个类:
- 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这个方法的前面加
- long start = System.currentTimeMillis();
- 后面加 long end= System.currentTimeMillis() 最后输出下end-start即可
javassist不只是这些功能,还有其他功能。后面再介绍点。
另外一种用javassist的方式也很简单,而且不用在这时改变源代码。
例子如下:
- 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");
- }
- }
运行结果如下:
- hello world
- Call to method sayHello took 3000 ms.
上面这个例子,是可以直接运行的。
javassist不只是这些功能,还有一些其他很好的功能,后面有空再记录下。