Java 字节码变更框架实现 JVM 热加载

导入

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 字节码热加载

https://www.tandi.wiki/%E5%9F%BA%E4%BA%8EJava%E6%8E%A2%E9%92%88%E4%B8%8E%E5%AD%97%E8%8A%82%E7%A0%81%E6%A1%86%E6%9E%B6%E6%9D%A5%E5%8A%A8%E6%80%81%E4%BF%AE%E6%94%B9%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%97%B6%E8%A1%8C%E4%B8%BA/

添加注解

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.

 

发布了2 篇原创文章 · 获赞 1 · 访问量 3084
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览