import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
public class JassistLearn {
public static void main(String[] argv) {
try {
CtClass clas = ClassPool.getDefault().get("Bean");
addTiming(clas,"show");
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CannotCompileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void addTiming(CtClass clas, String mname)
throws NotFoundException, CannotCompileException, IOException {
/* Retrieves methods with the specified name among the methods
* declared in the class. Multiple methods with different parameters
* may be returned.*/
CtMethod mold = clas.getDeclaredMethod(mname);
//修改当前方法名称为一个临时名称
String nname = mname+"$impl";
mold.setName(nname);
/* Creates a copy of a method with a new name.
* This method is provided for creating
* a new method based on an existing method.
* This is a convenience method for calling
* {@link CtMethod#CtMethod(CtMethod, CtClass, ClassMap) this constructor}.
* See the description of the constructor for particular behavior of the copying.
* 拷贝一个新的方法,内容跟当前方法一致,方法名与当前方法原有名称一致。后面主要修改新方法的
* 方法体的内容。
* */
CtMethod mnew = CtNewMethod.copy(mold, mname, clas, null);
String type = mold.getReturnType().getName();
StringBuffer body = new StringBuffer();
//在新方法体开始处增加一个变量start标识当前执行时间点
body.append("{\nlong start = System.currentTimeMillis();\n");
if (!"void".equals(type)) {
body.append(type + " result = ");
}
//原方法运行,格式为方法名+参数,($$)代表参数
body.append(nname + "($$);\n");
//在原方法执行后打印当前时间点。统计前后时间差可以算出原方法的执行耗时
body.append("System.out.println(\"Call to method " + mname +
" took \" +\n (System.currentTimeMillis()-start) + " +
"\" ms.\");\n");
if (!"void".equals(type)) {
body.append("return result;\n");
}
body.append("}");
//将方法体设置到新方法内
mnew.setBody(body.toString());
//将新方法添加到原方法所在类
clas.addMethod(mnew);
//更改原方法所在class文件,刷新到磁盘,完成字节码修改
clas.writeFile("D:/eclipse/server/JavaSistLearn/bin");
}
}