导入
Instrument介绍:https://www.ibm.com/developerworks/cn/java/j-lo-jse61/index.html
https://m.aliyun.com/yunqi/articles/60539
Javassist
http://erhu.party/2016/11/17/javassist-turorial-1/
Java Agent 字节码热加载
添加注解
public void addAnnotation(CtClass ctClass){
ConstPool constPool = ctClass.getClassFile().getConstPool();
try {
Object[] annotations = ctClass.getAnnotations();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
AnnotationsAttribute attribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("org.testng.annotations.Listeners", constPool);
annotation.addMemberValue(0, new ClassMemberValue("TestNgHook.class", constPool));
attribute.addAnnotation(annotation);
ctClass.getClassFile().addAttribute(attribute);
使用原有类和方法中字段
使用类中定义的属性(字段)
0是代表this也就是对象自己,所以直接使用0是代表this也就是对象自己,所以直接使用0.字段 进行赋值或者使用即可。
例如字段名字叫 status 就可以写成 $0.status=1;
使用方法中定义属性
Javassist也提供了一些特殊的变量来代表方法参 数:1,1,2,$args…要注意的是,插入的source文本中不能引用方法本地变量的声明,但是可以允许声明一个新的方法本地变量,除非在程序 编译时加入-g选项。
0代表的是this,0代表的是this,1代表方法参数的第一个参数、2代表方法参数的第二个参数,以此类推,2代表方法参数的第二个参数,以此类推,N代表是方法参数的第N个。
使用字段遇到问题
javassist [source error] bad filed access
The insertBefore, insertAfter and other such methods cannot access any local variable but can access method parameter of the method by their names. no such field error occurs if attempt is made to access local variable.