zoukankan      html  css  js  c++  java
  • 动态字节码技术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();
            }
        }
    
    }
  • 相关阅读:
    缺陷与出路——一个游戏开发者的反思(转自《大众软件》)
    Arcengine 根据坐标串生成几何图形
    C#Arcengine通过坐标点生成面(环形)
    解析XML文件
    arcgis下载地址
    C#读写txt文件的两种方法介绍
    可伸缩性最佳实践:来自eBay的经验[精华强贴, 转之]
    请问怎样才能监视数据库表的变化?[转]
    VS2010中,在新建项目的时候,删除默认新建路径或曾经使用过的路径
    VS2010注册表垃圾清理
  • 原文地址:https://www.cnblogs.com/moris5013/p/11039997.html
Copyright © 2011-2022 走看看