使用javassist動態(tài)生成類的配置代碼
說明:
Javassist(JAVA 編程 ASSISTant)使 Java 字節(jié)碼操作變得簡單。 它是一個用 Java 編輯字節(jié)碼的類庫。它使 Java 程序能夠在運行時定義新類,并在 JVM 加載時修改類文件。 與其他類似的字節(jié)碼編輯器不同,Javassist 提供兩個級別的 API:源級別和字節(jié)碼級別。 如果用戶使用源級 API,他們可以在不知道 Java 字節(jié)碼規(guī)范的情況下編輯類文件。 整個 API 僅使用 Java 語言的詞匯表進行設(shè)計。 您甚至可以以源文本的形式指定插入的字節(jié)碼;Javassist 即時編譯它。 另一方面,字節(jié)碼級 API 允許用戶直接編輯類文件作為其他編輯器。
配置環(huán)境:
- javassist依賴:
<dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.29.1-GA</version> </dependency>
- 環(huán)境配置:
–add-opens java.base/java.lang=ALL-UNNAMED
–add-opens java.base/sun.net.util=ALL-UNNAMED

使用javassist生成類:
代碼:
package com.user;
import javassist.*;
import java.lang.reflect.Method;
public class JavassistTest {
public static void main(String[] args) throws Exception{
//獲取類池
ClassPool pool = ClassPool.getDefault();
//通過類路徑創(chuàng)建類
CtClass ctClass = pool.makeClass("com.user.Test");
//為類創(chuàng)建方法(參數(shù):1.方法返回值類型 2.方法名 3.方法形參列表 4.方法所屬類)
CtMethod ctMethod = new CtMethod(CtClass.voidType, "execute", new CtClass[]{}, ctClass);
//設(shè)置方法的修飾符列表
ctMethod.setModifiers(Modifier.PUBLIC);
//設(shè)置方法體
ctMethod.setBody("{System.out.println(\"hello world\");}");
//給類添加方法
ctClass.addMethod(ctMethod);
//測試:使用反射機制測試方法調(diào)用
Class<?> aClass = ctClass.toClass();
Object o = aClass.newInstance();
Method method = aClass.getDeclaredMethod("execute");
method.invoke(o);
}
}執(zhí)行結(jié)果:

使用javassist生成類并實現(xiàn)接口:
接口已定義好:
package com.user;
public interface Dao {
public int insert();
public int delete();
public int update();
public void select();
}代碼:
package com.user;
import javassist.*;
import java.lang.reflect.Method;
import java.util.Arrays;
public class JavassistTestImpl {
public static void main(String[] args) throws Exception {
//獲取類池
ClassPool pool = ClassPool.getDefault();
//制造類
CtClass ctClass = pool.makeClass("com.user.TestImpl");
//制造接口
CtClass ctInterface = pool.makeInterface("com.user.Dao");
//類實現(xiàn)接口
ctClass.addInterface(ctInterface);
//獲取接口中的所有方法
Method[] methods = Dao.class.getDeclaredMethods();
//類實現(xiàn)接口中的所有方法
Arrays.stream(methods).forEach(method->{
try {
//拼接方法頭+方法體
StringBuilder sb = new StringBuilder();
sb.append("public");//方法修飾符
sb.append(" ");
sb.append(method.getReturnType().getName());//方法返回值類型
sb.append(" ");
sb.append(method.getName());//方法名
sb.append("(");
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
sb.append(parameterTypes[i].getName());//參數(shù)類型
sb.append(" ");
sb.append("arg"+i);//參數(shù)名,隨意指定,但不能重名
if(i != parameterTypes.length-1) {
sb.append(",");
}
}
sb.append(")");
sb.append("{");
String simpleName = method.getReturnType().getSimpleName();//根據(jù)返回值類型寫return語句
if("String".equals(simpleName)){
sb.append("return \"hello\";");
}else if("int".equals(simpleName)){
sb.append("return 1;");
}else if("void".equals(simpleName)){
sb.append("System.out.println(\"hello\");");
}
sb.append("}");
//創(chuàng)建方法(參數(shù):方法頭+方法體,所屬類)
CtMethod ctMethod = CtNewMethod.make(sb.toString(),ctClass);
ctClass.addMethod(ctMethod);
} catch (CannotCompileException e) {
e.printStackTrace();
}
});
//測試
Class<?> aClass = ctClass.toClass();
Dao o = (Dao)aClass.newInstance();
o.select();
System.out.println(o.insert());
}
}
執(zhí)行結(jié)果:

到此這篇關(guān)于使用javassist動態(tài)生成類的文章就介紹到這了,更多相關(guān)javassist動態(tài)生成類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java的接口調(diào)用時的權(quán)限驗證功能的實現(xiàn)
這篇文章主要介紹了Java的接口調(diào)用時的權(quán)限驗證功能的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
Spring IOC源碼剖析_如何整體認知Spring體系結(jié)構(gòu)
這篇文章主要介紹了Spring IOC源碼剖析_如何整體認知Spring體系結(jié)構(gòu)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
java實現(xiàn)一個接口調(diào)取另一個接口(接口一調(diào)取接口二)
這篇文章主要介紹了java實現(xiàn)一個接口調(diào)取另一個接口(接口一調(diào)取接口二),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

