Overview
Javassist is a bytecode editing tool that allows you to edit and generate Java-generated bytecode directly to achieve the effect of dynamic modification of the. class file. Skilled use of this set of tools allows Java programming to be closer to programming with dynamic languages. Tutorials maven Dependencies
Pom.xml
<dependency>
<groupId>org.javassist</groupId>
<artifactid>javassist</ artifactid>
<version>3.20.0-GA</version>
</dependency>
API Tutorial
1. Create a new class
Classpool pool = Classpool.getdefault ();
Define class
Ctclass Stuclass = Pool.makeclass ("com.ricky.Student");
Of course, if a class already exists, you can load it directly, as follows:
Ctclass cc = Pool.get ("java.lang.String");
2. Construct class member variable
ID attribute
Ctfield idfield = new Ctfield (ctclass.longtype, "id", stuclass);
Stuclass.addfield (IDfield);
3, the construction class method
Ctmethod GetMethod = ctnewmethod.make ("public int getage () {return this.age;}", Stuclass);
Ctmethod Setmethod = ctnewmethod.make ("public void setage (int age) {this.age = age;}", Stuclass);
Stuclass.addmethod (GetMethod);
Stuclass.addmethod (Setmethod);
Application Example
1, dynamic construction of a class
Package com.ricky.codelab.javassist;
Import java.io.IOException;
Import Java.lang.reflect.Field;
Import Java.lang.reflect.Method;
Import Java.util.Arrays; Import Javassist.
Cannotcompileexception; Import Javassist.
Classpool; Import Javassist.
Ctclass; Import Javassist.
Ctfield; Import Javassist.
Ctmethod; Import Javassist.
Ctnewmethod; Import Javassist.
Notfoundexception; /** * Dynamic Construction class * @author Ricky * * */public class Javassistdemo {public static void main (string[] args) throws C
Annotcompileexception, IOException, notfoundexception {classpool pool = Classpool.getdefault ();
Define class Ctclass Stuclass = Pool.makeclass ("com.ricky.Student");
Load class//Ctclass CC = Pool.get (classname);
id attribute Ctfield IDfield = new Ctfield (ctclass.longtype, "id", stuclass);
Stuclass.addfield (IDfield);
The Name property Ctfield NameField = new Ctfield (Pool.get ("java.lang.String"), "name", Stuclass); Stuclass.addfield (NamefiELD);
Age attribute Ctfield Agefield = new Ctfield (Ctclass.inttype, "age", Stuclass);
Stuclass.addfield (Agefield);
Ctmethod GetMethod = ctnewmethod.make ("public int getage () {return this.age;}", Stuclass);
Ctmethod Setmethod = ctnewmethod.make ("public void setage (int age) {this.age = age;}", Stuclass);
Stuclass.addmethod (GetMethod);
Stuclass.addmethod (Setmethod);
Stuclass.writefile ("F:\\practice_demo");
Class<?> clazz = Stuclass.toclass ();
System.out.println ("Class:" +clazz.getname ());
SYSTEM.OUT.PRINTLN ("------------attribute list------------");
field[] fields = Clazz.getdeclaredfields ();
for (Field field:fields) {System.out.println (Field.gettype () + "\ T" +field.getname ());
} System.out.println ("------------method list------------");
Method method[] Methods = Clazz.getdeclaredmethods (); For (method Method:methods) {SYSTEM.OUT.PRintln (Method.getreturntype () + "T" +method.getname () + "T" +arrays.tostring (Method.getparametertypes ());
}
}
}
2, specifying the parent class
Package com.ricky.codelab.javassist;
Import java.io.IOException;
Import Java.lang.reflect.Field;
Import Java.lang.reflect.Method;
Import Java.util.Arrays; Import Javassist.
Cannotcompileexception; Import Javassist.
Classpool; Import Javassist.
Ctclass; Import Javassist.
Ctfield; Import Javassist.
Notfoundexception; public class Javassistextenddemo {public static void main (string[] args) throws Cannotcompileexception, IOException,
notfoundexception {Classpool pool = Classpool.getdefault ();
Define class Ctclass Stuclass = Pool.makeclass ("com.ricky.Student");
Sets the parent class Stuclass.setsuperclass (Pool.get ("Com.ricky.codelab.javassist.domain.Person"));
Hobbies Property Ctfield Agefield = new Ctfield (Pool.getctclass ("Java.util.List"), "hobbies", stuclass);
Stuclass.addfield (Agefield);
Class<?> clazz = Stuclass.toclass ();
System.out.println ("Class:" +clazz.getname ()); System.out.println ("------------Property list------------");
field[] fields = Clazz.getdeclaredfields ();
for (Field field:fields) {System.out.println (Field.gettype () + "\ T" +field.getname ());
} System.out.println ("------------method list------------");
Method method[] Methods = Clazz.getmethods (); For (method Method:methods) {System.out.println (Method.getreturntype () + "\ T" +method.getname () + "T" +arrays.tost
Ring (Method.getparametertypes ()));
}
}
}
3, dynamic injection code
Package com.ricky.codelab.javassist;
Import java.io.IOException; Import Javassist.
Cannotcompileexception; Import Javassist.
Classpool; Import Javassist.
Ctclass; Import Javassist.
Ctmethod; Import Javassist.
Ctnewmethod; Import Javassist.
Notfoundexception; /** * Dynamic Injection code * * @author Ricky * */public class Javassistinsertdemo {public static void main (string[] args) t Hrows cannotcompileexception, IOException, Notfoundexception, Instantiationexception, IllegalAccessException {Cl
Asspool pool = Classpool.getdefault ();
Define class Ctclass Ctclass = Pool.get ("Com.ricky.codelab.javassist.Calculator");
The method name that needs to be modified String mname = "Getsum";
Ctmethod mold = Ctclass.getdeclaredmethod (mname);
Modify the original method name String Nname = mname + "$impl";
Mold.setname (Nname);
Create a new method that duplicates the original method Ctmethod mnew = ctnewmethod.copy (Mold, mname, ctclass, NULL);
The main injection code stringbuffer BODY = new StringBuffer (); Body.append ("{\nlong start = System.currenttimemillis (); \ n");
Invoke the original code, similar to Method ();($$) to represent all parameters Body.append (Nname + "($$); \ n"); Body.append ("System.out.println" ("Call to") + Mname + "took \" +\n (System.currenttimemillis ()-sta
RT) + "+" \ "ms.\"); \ n ");
Body.append ("}");
Replace the new method Mnew.setbody (Body.tostring ());
Add New Method Ctclass.addmethod (mnew);
Calculator Calculator = (Calculator) ctclass.toclass (). newinstance ();
Calculator.getsum (10000);
} class Calculator {public void getsum (long n) {long sum = 0;
for (int i = 0; i < n; i++) {sum = i;
} System.out.println ("n=" +n+ ", sum=" +sum);
}
}