Javassist 是一个开源的分析、编辑和创建 Java 字节码的类库,被广泛用于程序性的类文件操作和运行时 AOP 框架,能动态改变类的结构,或者动态生成类。
关于javassist和反射
Javassist 不是通过反射来实现的,而是通过直接操作字节码来实现的。
在 Java 中,每个类都会被编译成一个或多个字节码文件(.class 文件)。这些字节码文件包含了 Java 虚拟机(JVM)需要执行类中的代码的所有信息。Javassist 可以读取这些字节码文件,修改它们,然后写回去,或者直接创建新的字节码文件。这使得 Javassist 能够在运行时动态地创建和修改类。
反射(Reflection)则是 Java 提供的一个特性,它允许程序在运行时获取类的信息(如类名、方法、字段等),并动态地调用方法、访问字段等。与 Javassist 不同,反射不能修改类的结构,只能动态地使用类。
所以,尽管 Javassist 和反射都能在运行时动态地操作类,但是它们的实现机制和能力是不同的。
下面是些使用javassist的小demo
public class JavaSsistDemo1 {
    public static void main(String[] args) throws Exception {
        // 获取类池
        ClassPool pool = ClassPool.getDefault();
        // 创建类
        CtClass cc = pool.makeClass("com.example.GeneratedPOJO");
        // 创建字段,字段的类型,字段名称
        CtField fooField = new CtField(pool.get("java.lang.String"), "foo", cc);
        //设置私有化
        fooField.setModifiers(Modifier.PRIVATE);
        //类中添加该字段
        cc.addField(fooField);
        //创建get方法
        cc.addMethod(CtNewMethod.getter("getFoo", fooField));
        //创建set方法
        cc.addMethod(CtNewMethod.setter("setFoo", fooField));
        CtMethod helloMethod = CtNewMethod.make(
                "public void hello() { System.out.println(\"Hello Javassist!\"); }",
                cc
        );
        cc.addMethod(helloMethod);
        //可以选择写入磁盘,也可以不写入直接在内存中使用
        cc.writeFile("J:\\javassist\\javassist-01\\target\\classes\\");
        //获得类对象
        Class<?> clazz = cc.toClass();
        //这里用Class.forName("")也是可以的,就是没有必要
        //Class<?> clazz1 = Class.forName("com.example.GeneratedPOJO");
        //实例化
        Object instance = clazz.newInstance();
        Method getter = clazz.getMethod("getFoo");
        System.out.println(getter.invoke(instance));
        Method hello = clazz.getMethod("hello");
        hello.invoke(instance);
        //如果方法有返回值
        String result = (String) hello.invoke(instance);
        System.out.println(result);  // prints "Hello Javassist!"
    }
//    public static void main(String[] args) throws Exception {
//        // 获取类池
//        ClassPool pool = ClassPool.getDefault();
//        // 创建类
//        CtClass ctClass = pool.makeClass("com.com.example.GeneratedPOJO");
//        // 创建⽅法
//        // 1.返回值类型 2.⽅法名 3.形式参数列表 4.所属类
//        CtMethod ctMethod = new CtMethod(CtClass.voidType, "execute", new
//                CtClass[]{}, ctClass);
//        // 设置⽅法的修饰符列表
//        ctMethod.setModifiers(Modifier.PUBLIC);
//        // 设置⽅法体
//        ctMethod.setBody("{System.out.println(\"hello world\");}");
//        // 给类添加⽅法
//        ctClass.addMethod(ctMethod);
//        // 调⽤⽅法
//        Class<?> aClass = ctClass.toClass();
//        Object o = aClass.newInstance();
//        Method method = aClass.getDeclaredMethod("execute");
//        method.invoke(o);
//    }
} 
cc.toClass() 是动态创建并加载类,而 Class.forName() 是加载已经存在的类。
关于Mybatis的demo,我们当里面只有一个方法

public static void main(String[] args) throws CannotCompileException, IllegalAccessException, InstantiationException {
        //模仿Mybatis动态创建实现类
        //获取类池
        ClassPool pool=ClassPool.getDefault();
        //制造类
        CtClass ctClass=pool.makeClass("com.example.UserDaoImpl");
        //制造接口
        //CtClass ctInterface=pool.makeClass("com.example.UserDao");
        //注意javassits的类加载器和UserDao加载器可能不是同一个
        
        //让类实现接口 
        //这里其实用CtClass ctInterface = pool.get("com.example.UserDao");更加合适
        CtClass ctInterface = pool.get("com.example.UserDao");
        ctClass.addInterface(ctInterface);//UserDaoImpl implements UserDao
        //实现接口中的方法,这个比较麻烦,这里好比我们已经知道了所有方法什么的
        //制造方法
        CtMethod ctMethod=CtMethod.make("public void delete(){System.out.println(\"delete biubiubiu\");}",ctClass);
        //将方法添加到类中
        ctClass.addMethod(ctMethod);
        //在内存中生成类,同时将生成的类加载到JVM当中
        Class<?> aClass = ctClass.toClass();
        UserDao userDao=(UserDao) aClass.newInstance();
        System.out.println(userDao.getClass());
        userDao.delete();
    } 
 
模拟实现Mapper接口所有方法

public static void main(String[] args) throws CannotCompileException, IllegalAccessException, InstantiationException, NotFoundException {
        //模仿Mybatis动态创建实现类
        //获取类池
        ClassPool pool=ClassPool.getDefault();
        //制造类
        CtClass ctClass=pool.makeClass("com.example.UserDaoImpl");
        //获取接口
        CtClass ctInterface=pool.get("com.example.UserDao");
        //让类实现接口
        ctClass.addInterface(ctInterface);//UserDaoImpl implements UserDao
        //实现接口中所有的方法
        //获取接口中所有的方法
        Method[] methods=UserDao.class.getDeclaredMethods();
        //遍历中实现抽象方法,然后把方法放到了类中
        Arrays.stream(methods).forEach(method->{
            //method是接口中所有的抽象方法
            //把method抽象方法给实现了
            CtMethod ctMethod=null;
            try {
                StringBuilder methodCode=new StringBuilder();
                methodCode.append("public ");//修饰符列表
                methodCode.append(method.getReturnType().getName());//追加返回值类型
                methodCode.append(" ");
                methodCode.append(method.getName());//追加方法名
                methodCode.append("(");
                //也许方法有参数
                Class<?>[] parameterTypes = method.getParameterTypes();
                for(int i=0;i<parameterTypes.length;i++){
                    Class<?> parameterType = parameterTypes[i];
                    methodCode.append(parameterType.getName());//参数类型
                    methodCode.append(" ");
                    methodCode.append("arg"+i);//变量名随意,不重复就行
                    if(i!=parameterTypes.length-1){
                        methodCode.append(",");
                    }
                }
                methodCode.append("){System.out.println(1111);");
                //动态添加return语句
                String simpleName = method.getReturnType().getSimpleName();//返回值类型的简类名
                if("void".equals(simpleName)){
                }else if("int".equals(simpleName)){
                    methodCode.append("return 1;");
                }else if("String".equals(simpleName)) {
                    methodCode.append("return \"hello\";");
                }else if("Map".equals(simpleName)) {
                    methodCode.append("Map<String,String> map=new HashMap<>(); return map;");
                }
                methodCode.append("}");
                System.out.println(methodCode);
                //制造方法
                ctMethod=CtMethod.make(methodCode.toString(),ctClass);
                //将方法添加到类中
                ctClass.addMethod(ctMethod);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        //在内存中生成类,同时将生成的类加载到JVM当中
        Class<?> aClass = ctClass.toClass();
        //创建对象
        UserDao userDao=(UserDao) aClass.newInstance();
        System.out.println(userDao.getClass());
        //调用方法
        userDao.delete();
        userDao.selectasd("as");
    } 
                














