I saw the proxy part of Hibernate in the past two days. The first reaction was that the underlying layer used reflection and generated a proxy class for the user entity. Later, I realized that reflection did not have any ability to generate new classes, so I naturally found Javassist (download address).
Most of the tutorials searched online are explained to the Javassist API, but in the end, there is often no loading process. When the author imitates these tutorials for class loading, the results loaded are the original class and no content with the bytecode modified.
After some exploration, the author found that the last step in most tutorials on the Internet, saving bytecode is used to save the bytecode. After checking its function structure, it found that it also has a String type overload. Because under Eclipse, the root position of the bytecode is not ".//" but ".//bin", and another overload of writeFile is likely to be the parameter specifying the root position of the bytecode. After some changes, I found that it was true.
The following is the demo code:
This is the structure of the author's project:
Editable.java: package com.thrblock.javassist; public class Editable { public void showInfo(){ System.out.println("InfoDefault!"); } } Main.java: package com.thrblock.javassist;import java.io.IOException;import javassist.CannotCompileException;import javassist.ClassPool;import javassist.CtClass;import javassist.CtMethod;import javassist.CtNewMethod;import javassist.NotFoundException;public class Main {public static void main(String[] args) {ClassPool pool = ClassPool.getDefault();try{pool.insertClassPath(".//bin");//Set the root path. (The root path set here is obviously not used by writeFile) CtClass cc = pool.makeClass("com.thrblock.javassist.EditableChanged");//Simulate the Hibernate proxy mode, we create a new class cc.setSuperclass(pool.get("com.thrblock.javassist.Editable"));//Set its parent class CtMethodcm = CtNewMethod.make("public void showInfo(){super.showInfo();System.out.println(/"CustomInsertHAHA!/");}",cc);//Add a method, note that it overrides the methods in the parent class. cc.addMethod(cm);cc.writeFile(".//bin");//This is more important. The result of the null parameter is that it is not saved in the eclipse bytecode root path. }catch (NotFoundException | CannotCompileException | IOException e) {e.printStackTrace();}try{Class<?> cl = Class.forName("com.thrblock.javassist.EditableChanged");//Load our new class Editableed = (Editable) cl.newInstance();//Because its inheritance is the same as the load principle in Hibernate. ed.showInfo();//Calling the method. }catch (ClassNotFoundException | InstantiationException |IllegalAccessException e) {e.printStackTrace();}}}Print result:
InfoDefault!
CustomInsertHAHA!
Other notes:
Since we have generated a class, if the class name is the same as the original class name, the class file will be overwritten. However, if the class has been loaded by the JVM before modification, the modified part will not take effect and the JVM must be restarted.
Summarize
The above is all the content of this article about the correct usage method of Javassist under Eclipse. I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!