溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

動(dòng)態(tài)字節(jié)碼技術(shù) javassist 初探

發(fā)布時(shí)間:2020-08-06 03:15:09 來源:網(wǎng)絡(luò) 閱讀:748 作者:灰白世界 欄目:編程語(yǔ)言

字節(jié)碼應(yīng)用場(chǎng)景
AOP 技術(shù)、Lombok 去除重復(fù)代碼插件、動(dòng)態(tài)修改 class 文件等
字節(jié)碼技術(shù)優(yōu)勢(shì)
Java 字節(jié)碼增強(qiáng)指的是在 Java 字節(jié)碼生成之后,對(duì)其進(jìn)行修改,增強(qiáng)其功能,這種方式相當(dāng)于對(duì)應(yīng)用程序的二進(jìn)制文件進(jìn)行修改,Java 字節(jié)碼增強(qiáng)主要是為了減少冗余代碼,提高性能等 實(shí)現(xiàn)字節(jié)碼增強(qiáng)的主要步驟為:
修改字節(jié)碼,在內(nèi)存中獲取到原來的字節(jié)碼,然后通過一些工具(如 ASM,Javaasist)來修改它的byte[]數(shù)組,得到一個(gè)新的byte數(shù)組
使修改后的字節(jié)碼生效

自定義 ClassLoader 來加載修改后的字節(jié)碼
替換掉原來的字節(jié)碼,在 JVM 加載用戶的 Class 時(shí),攔截,返回修改后的字節(jié)碼,或者在運(yùn)行時(shí),使用Instrumentation.redefineClasses 方法來替換掉原來的字節(jié)碼
常見的字節(jié)碼操作類庫(kù)
BCEL
Byte Code Engineering Library(BCEL),這是Apache Software Foundation的 Jakarta 項(xiàng)目的一部分,BCEL 是 Java classworking 廣泛使用的一種框架,它可以讓您深入jvm匯編語(yǔ)言進(jìn)行類庫(kù)操作的細(xì)節(jié),BCEL 與 javassist 有不同的處理字節(jié)碼方法,BCEL 在實(shí)際的 JVM 指令層次上進(jìn)行操作(BCEL 擁有豐富的 JVM 指令集支持)而 javassist 所強(qiáng)調(diào)的是源代碼級(jí)別的工作
ASM
是一個(gè)輕量級(jí) Java 字節(jié)碼操作框架,直接涉及到JVM底層的操作和指令,高性能,高質(zhì)量
CGLB
生成類庫(kù),基于ASM實(shí)現(xiàn)
javassist
是一個(gè)開源的分析、編輯和創(chuàng)建 Java 字節(jié)碼的類庫(kù),性能較 ASM 差,跟 CGLIB 差不多,但是使用簡(jiǎn)單,很多開源框架都在使用它
Javassist 中最為重要的是 ClassPool、CtClass 、CtMethod、CtField
ClassPool:一個(gè)基于HashMap實(shí)現(xiàn)的 CtClass 對(duì)象容器,其中鍵是類名稱,值是表示該類的 CtClass 對(duì)象,默認(rèn)的ClassPool 使用與底層 JVM 相同的類路徑,因此在某些情況下,可能需要向 ClassPool 添加類路徑或類字節(jié)
CtClass:表示一個(gè)類,這些 CtClass 對(duì)象可以從 ClassPool 獲得
CtMethods:表示類中的方法
CtFields :表示類中的字段
優(yōu)勢(shì):
比反射開銷小、性能高
操作字節(jié)碼可以動(dòng)態(tài)生成新的類,動(dòng)態(tài)修改類(添加、刪除、修改屬性或方法)
javassist 外層 API 和反射類似
主要有 CtClass、CtMethod、CtField 組成,執(zhí)行反射中的 java.lang.Class、java.lang.reflect.Method、 java.lang.reflect.Method .Field 中的操作
劣勢(shì):
不支持 JDK5 的新語(yǔ)法,包括泛型、枚舉,不支持注解修改
不支持?jǐn)?shù)組初始化
不支持內(nèi)部類和匿名類
不支持 continue 和 break
動(dòng)態(tài)創(chuàng)建類
public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException {
ClassPool pool = ClassPool.getDefault();
// 創(chuàng)建User
CtClass userClass = pool.makeClass("com.kernel.entity.User");
// 創(chuàng)建屬性
CtField nameField = CtField.make("private String name;", userClass);
CtField ageField = CtField.make("private Integer age;", userClass);
// 添加屬性
userClass.addField(nameField);
userClass.addField(ageField);
// 創(chuàng)建方法
CtMethod getName = CtMethod.make("public String getName() {return name;}", userClass);
CtMethod setName = CtMethod.make("public void setName(String name) {this.name = name;}", userClass);
// 添加方法
userClass.addMethod(getName);
userClass.addMethod(setName);
// 創(chuàng)建構(gòu)造器
CtConstructor constructor = new CtConstructor(new CtClass[]{pool.get("java.lang.String"), pool.get("java.lang.Integer")}, userClass);
// 設(shè)置內(nèi)容
constructor.setBody("{this.name = name;this.age = age;}");
// 添加構(gòu)造器
userClass.addConstructor(constructor);
userClass.writeFile("D:\Codes\Java\Performance\jvm-day03\src\main\java\com\kernel\test");
}
動(dòng)態(tài)添加并執(zhí)行方法
public static void main(String[] args) {
try {
ClassPool pool = ClassPool.getDefault();
// 讀取com.kernel.User
CtClass userClass = pool.get("com.kernel.User");
// 創(chuàng)建方法,設(shè)置方法返回值
CtMethod method = new CtMethod(CtClass.voidType, "sum", new CtClass[] { CtClass.intType, CtClass.intType },
userClass);
// 設(shè)置方法內(nèi)容
method.setBody("{System.out.println(\"sun:\" + ($1 + $2));}");
// 添加方法
userClass.addMethod(method);
userClass.writeFile("D:\Codes\Java\Performance\jvm-day03\src\main\java\com\kernel\test");
// 動(dòng)態(tài)執(zhí)行方法
Class clazz = userClass.toClass();
Object newInstance = clazz.newInstance();
// 獲得方法
Method sumMethod = clazz.getDeclaredMethod("sum", int.class, int.class);
sumMethod.invoke(newInstance, 2, 5);
} catch (Exception e) {
e.printStackTrace();
}
}

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI