使用javassist動(dòng)態(tài)生成類的配置代碼
說(shuō)明:
Javassist(JAVA 編程 ASSISTant)使 Java 字節(jié)碼操作變得簡(jiǎn)單。 它是一個(gè)用 Java 編輯字節(jié)碼的類庫(kù)。它使 Java 程序能夠在運(yùn)行時(shí)定義新類,并在 JVM 加載時(shí)修改類文件。 與其他類似的字節(jié)碼編輯器不同,Javassist 提供兩個(gè)級(jí)別的 API:源級(jí)別和字節(jié)碼級(jí)別。 如果用戶使用源級(jí) API,他們可以在不知道 Java 字節(jié)碼規(guī)范的情況下編輯類文件。 整個(gè) API 僅使用 Java 語(yǔ)言的詞匯表進(jìn)行設(shè)計(jì)。 您甚至可以以源文本的形式指定插入的字節(jié)碼;Javassist 即時(shí)編譯它。 另一方面,字節(jié)碼級(jí) 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();
//通過(guò)類路徑創(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);
//測(cè)試:使用反射機(jī)制測(cè)試方法調(diào)用
Class<?> aClass = ctClass.toClass();
Object o = aClass.newInstance();
Method method = aClass.getDeclaredMethod("execute");
method.invoke(o);
}
}執(zhí)行結(jié)果:

使用javassist生成類并實(shí)現(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");
//類實(shí)現(xiàn)接口
ctClass.addInterface(ctInterface);
//獲取接口中的所有方法
Method[] methods = Dao.class.getDeclaredMethods();
//類實(shí)現(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語(yǔ)句
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();
}
});
//測(cè)試
Class<?> aClass = ctClass.toClass();
Dao o = (Dao)aClass.newInstance();
o.select();
System.out.println(o.insert());
}
}
執(zhí)行結(jié)果:

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

