• 动态字节码技术Javassist


    字节码技术可以动态改变某个类的结构(添加/删除/修改  新的属性/方法)

    关于字节码的框架有javassist,asm,bcel等

    引入依赖

    <dependency>
         <groupId>javassist</groupId>
          <artifactId>javassist</artifactId>
          <version>3.12.1.GA</version>
    </dependency>

    生成字节码

    //创建字节码文件
    public class CreateClass {
    
        public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException {
            ClassPool pool = ClassPool.getDefault();
            // 1.创建user类
            CtClass userClass = pool.makeClass("com.irish.entity.User");
            // 2.创建name 和age属性
            CtField nameField = CtField.make("private String name;", userClass);
            CtField ageField = CtField.make("private Integer age;", userClass);
            // 3.添加属性
            userClass.addField(nameField);
            userClass.addField(ageField);
            // 4.创建方法
            CtMethod nameMethod = CtMethod.make("public String getName() {return name;}", userClass);
            // 5.添加方法
            userClass.addMethod(nameMethod);
            // 6.添加构造函数
            CtConstructor ctConstructor = new CtConstructor(
                    new CtClass[] { pool.get("java.lang.String"), pool.get("java.lang.Integer") }, userClass);
    
            ctConstructor.setBody("    { this.name = name; this.age = age; }");
            userClass.addConstructor(ctConstructor);
    
            // 生成class文件
            userClass.writeFile("F:/test");
            System.out.println("生成字节码,成功!");
        }
    
    }

    读取字节码后,对字节码新增方法,然后执行该方法

    这里的User类要存在,UpdateClass 才可以读取出他的字节码后再修改

    public class User {
    
        private String name;
        private Integer age;
    
    }
    //动态修改字节码文件
    public class UpdateClass {
    
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) {
            try {
                ClassPool pool = ClassPool.getDefault();
                // 读取com.irish.User
                CtClass userClass = pool.get("com.irish.User");
                CtMethod method = new CtMethod(CtClass.voidType, "sum", new CtClass[] { CtClass.intType, CtClass.intType },
                        userClass);
                method.setBody("{System.out.println("sun:" + ($1 + $2));}");
                // 添加方法
                userClass.addMethod(method);
                //将修改后的字节码写入到磁盘中,通过反编译工具,可以看到对类进行了修改
                userClass.writeFile("F:/test");
                // 动态执行方法
                Class clazz = userClass.toClass();
                Object newInstance = clazz.newInstance();
                Method sumMethod = clazz.getDeclaredMethod("sum", int.class, int.class);
                sumMethod.invoke(newInstance, 2, 5);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
  • 相关阅读:
    洛谷 P1360 [USACO07MAR]黄金阵容均衡Gold Balanced L…
    测试 10.23
    洛谷 P3130 [USACO15DEC]计数haybalesCounting Haybales
    洛谷 P1985 翻转棋
    codevs 1019 集合论与图论
    6、trait特质、包别名、文件、private[this]
    -_-#Error
    -_-#【乱码】URL中文参数
    【bug】【userAgent】极速模式与非极速模式存在差异
    -_-#【模块】getElementsByClassName
  • 原文地址:https://www.cnblogs.com/moris5013/p/11039997.html
Copyright © 2020-2023  润新知