说明
Javaassist 就是一个用来处理 Java 字节码的类库
Java 字节码以二进制的形式存储在 .class 文件中,每一个 .class 文件包含一个 Java 类或接口
Javaassist 可以在一个已经编译好的类中添加新的方法
,或者是修改已有的方法
Javaassist 同时也可以去生成一个新的类对象
,通过完全手动的方式
参考 https://www.cnblogs.com/rickiyang/p/11336268.html
依赖 1 2 3 4 5 <dependency > <groupId > org.javassist</groupId > <artifactId > javassist</artifactId > <version > 3.25.0-GA</version > </dependency >
创建一个 class 文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package com.theking.learn.javassist;import javassist.*;public class CreatePerson { public static void createPerson () throws Exception { ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass("com.theking.learn.javassist.Person" ); CtField param = new CtField (pool.get("java.lang.String" ), "name" , cc); param.setModifiers(Modifier.PRIVATE); cc.addField(param, CtField.Initializer.constant("xiaoming" )); cc.addMethod(CtNewMethod.setter("setName" , param)); cc.addMethod(CtNewMethod.getter("getName" , param)); CtConstructor cons = new CtConstructor (new CtClass []{}, cc); cons.setBody("{name = \"xiaohong\";}" ); cc.addConstructor(cons); cons = new CtConstructor (new CtClass []{pool.get("java.lang.String" )}, cc); cons.setBody("{$0.name = $1;}" ); cc.addConstructor(cons); CtMethod ctMethod = new CtMethod (CtClass.voidType, "printName" , new CtClass []{}, cc); ctMethod.setModifiers(Modifier.PUBLIC); ctMethod.setBody("{System.out.println(name);}" ); cc.addMethod(ctMethod); cc.writeFile("/Users/mac126/work/IDEA_Projects/maven_Javassist/src/main/java/" ); } public static void main (String[] args) { try { createPerson(); } catch (Exception e) { e.printStackTrace(); } } }
读取 .class 文件 1 2 3 4 5 ClassPool pool = ClassPool.getDefault();pool.appendClassPath("/Users/mac126/work/IDEA_Projects/maven_Javassist/src/main/java/" ); CtClass ctClass = pool.get("com.theking.learn.javassist.Person" );Object person = ctClass.toClass().newInstance();
反射方式调用方法 1 2 3 4 5 Method setName = person.getClass().getDeclaredMethod("setName" , String.class);setName.invoke(person, "zhangsan" ); Method printName = person.getClass().getDeclaredMethod("printName" );printName.invoke(person);
实现接口 1 2 3 4 5 6 7 8 9 10 11 12 CtClass codeClassI = pool.get("com.rickiyang.learn.javassist.PersonI" );CtClass ctClass = pool.get("com.theking.learn.javassist.Person" );ctClass.setInterfaces(new CtClass []{codeClassI}); PersonI person = (PersonI)ctClass.toClass().newInstance();System.out.println(person.getName()); person.setName("xiaolv" ); person.printName();
修改类对象 1 2 3 4 5 6 7 8 9 public class PersonService { public void getPerson () { System.out.println("get Person" ); } public void personFly () { System.out.println("oh my god,I can fly" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ClassPool pool = ClassPool.getDefault();CtClass cc = pool.get("com.theking.learn.javassist.PersonService" );CtMethod personFly = cc.getDeclaredMethod("personFly" );personFly.insertBefore("System.out.println(\"起飞之前准备降落伞\");" ); personFly.insertAfter("System.out.println(\"成功落地。。。。\");" ); CtMethod ctMethod = new CtMethod (CtClass.voidType, "joinFriend" , new CtClass []{}, cc);ctMethod.setModifiers(Modifier.PUBLIC); ctMethod.setBody("{System.out.println(\"i want to be your friend\");}" ); cc.addMethod(ctMethod); Object person = cc.toClass().newInstance();Method personFlyMethod = person.getClass().getMethod("personFly" );personFlyMethod.invoke(person); Method execute = person.getClass().getMethod("joinFriend" );execute.invoke(person);