电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Javassist如何操作Java 字節碼

瀏覽:13日期:2022-08-25 15:44:26

一、開篇

說起 AOP 小伙伴們肯定很熟悉,無論是 JDK 動態代理或者是 CGLIB 等,其底層都是通過操作 Java 字節碼來實現代理。常用的一些操作字節碼的技術有 ASM、AspectJ、Javassist 等。

ASM 其設計和實現是盡可能小而且快,更專注于性能。它在指令的層面來操作,所以使用它需要對 JVM 的指令有所了解,門檻較高,CGLIB 就使用了 ASM 技術。AspectJ 擴展了 Java 語言,定義了一系列 AOP 語法,在 JVM 中運行需要使用特定的編譯器生成遵守 Java 字節碼規范的 Class 文件,Spring AOP 使用了 AspectJ 。Javassist 直接使用 Java 編碼的形式操作字節碼,簡單易上手,性能高于反射,相比于 ASM 稍低。

二、Javassist 常用類

Javassist 抽象出一個 ClassPool 對象來操作 Java 類,可以通過 ClassPool.getDefault() 來獲取默認的 ClassPool 。常用的對象:

CtClass:代表一個 Class 的實例,可以通過類的全限定名來獲取 CtClass 對象,其中包含了對 Class 的各種操作。ClassPool:通過 HashTable 保存了路徑下的 CtClass 信息,key為類的全限定名稱,value 為類名對應的 CtClass 對象。CtMethod、CtField:抽象出類的方法和屬性,可以用于定義或修改方法和字段。

三、Javassist 的使用

1、依賴

<dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.27.0-GA</version></dependency>

2、代碼示例

// 獲取默認類池 ClassPool classPool = ClassPool.getDefault(); // 1. 創建空類 CtClass ctClass = classPool.makeClass('com.aysaml.demo.javassist.User'); // 2. 創建 String 類型的 name 字段 CtField field = new CtField(classPool.get('java.lang.String'), 'name', ctClass); // 設置字段訪問級別 private field.setModifiers(Modifier.PRIVATE); // 增加字段 ctClass.addField(field); // 3. 增加 getter & setter 方法 ctClass.addMethod(CtNewMethod.getter('getName', field)); ctClass.addMethod(CtNewMethod.setter('setName', field)); // 4. 增加無參構造方法:其中 $0 表示 this,$1 表示參數 CtConstructor noArgsCons = new CtConstructor(new CtClass[] {}, ctClass); noArgsCons.setBody('{$0.name='mark';}'); ctClass.addConstructor(noArgsCons); // 5. 增加有參構造方法 CtConstructor hasArgsCons = new CtConstructor(new CtClass[] {classPool.get('java.lang.String')}, ctClass); hasArgsCons.setBody('{$0.name=$1;}'); ctClass.addConstructor(hasArgsCons); // 6. 創建方法 CtMethod method = new CtMethod(CtClass.voidType, 'printName', new CtClass[] {}, ctClass); method.setBody('{System.out.println($0.name);}'); ctClass.addMethod(method); // 7. 生成類文件:可指定路徑,默認為當前項目根目錄 ctClass.writeFile(); // 8. 創建類實例 Object person = ctClass.toClass().newInstance();

3、如何實現類似 AOP 的功能

由上可見,Javassist 對于編程化的操作字節碼是很簡單易懂的,我們以在方法的開頭結尾打印信息為例:

public class Cat { /** 記錄喵喵喵的次數 */ private int num; public void miao() { this.num++; }}

我們要在 miao( ) 方法的前增加聲音輸出:

public static void main(String[] args) throws NotFoundException, CannotCompileException { ClassPool classPool = ClassPool.getDefault(); // 獲取 Cat 類的 CtClass 對象 CtClass catClass = classPool.get('com.aysaml.demo.javassist.Cat'); // 獲取 miao( ) 方法 CtMethod method = catClass.getDeclaredMethod('miao'); method.insertBefore('System.out.println('miao~');'); // 加載修改過的類,注意必須要保證調用前這個類沒有被加載過 catClass.toClass(); //測試 Cat cat = new Cat(); cat.miao(); }

注意到,在使用 catClass.toClass() 加載被修改過的類時,強調必須保證在調用前這個類沒有被加載過,否則會報 attempted duplicate class definition for name 異常。

我們知道一個類是不能被一個類加載器加載兩次的,所以為了解決這個問題,需要制定一個沒有加載過該類的 Classloader,Javassist 提供了一個 ClassLoader ,如下:

public class Cat { /** 記錄喵喵喵的次數 */ private int num; public void miao() { System.out.println('調用了 miao 方法'); this.num++; } public static void main(String[] args) throws Exception{ ClassPool classPool = ClassPool.getDefault(); // 獲取 Cat 類的 CtClass 對象 CtClass catClass = classPool.get('com.aysaml.demo.javassist.Cat'); // 獲取 miao( ) 方法 CtMethod method = catClass.getDeclaredMethod('miao'); method.insertBefore('System.out.println('miao~');'); // 重新設置一個 Classloader Loader classLoader = new Loader(classPool); Class clazz = classLoader.loadClass('com.aysaml.demo.javassist.Cat'); // 調用修改過的類的方法 clazz.getDeclaredMethod('miao').invoke(clazz.newInstance()); }}

執行結果為:

Javassist如何操作Java 字節碼

四、結語

關于 Javassist 暫時就說這么多了,更多使用方法參考官方 github wiki :

以上就是Javassist如何操作Java 字節碼的詳細內容,更多關于Javassist 操作Java 字節碼的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 减速机电机一体机_带电机减速器一套_德国BOSERL电动机与减速箱生产厂家 | 杭州画室_十大画室_白墙画室_杭州美术培训_国美附中培训_附中考前培训_升学率高的画室_美术中考集训美术高考集训基地 | 行星搅拌机,双行星搅拌机,动力混合机,无锡米克斯行星搅拌机生产厂家 | 领袖户外_深度旅游、摄影旅游、小团慢旅行、驴友网 | 深圳公司注册-工商注册公司-千百顺代理记账公司 | 真空粉体取样阀,电动楔式闸阀,电动针型阀-耐苛尔(上海)自动化仪表有限公司 | 超声波_清洗机_超声波清洗机专业生产厂家-深圳市好顺超声设备有限公司 | 多米诺-多米诺世界纪录团队-多米诺世界-多米诺团队培训-多米诺公关活动-多米诺创意广告-多米诺大型表演-多米诺专业赛事 | 深圳公司注册-工商注册代理-注册公司流程和费用_护航财税 | [品牌官网]贵州遵义双宁口腔连锁_贵州遵义牙科医院哪家好_种植牙_牙齿矫正_原华美口腔 | 换网器_自动换网器_液压换网器--郑州海科熔体泵有限公司 | China plate rolling machine manufacturer,cone rolling machine-Saint Fighter | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 密封无忧网 _ 专业的密封产品行业信息网 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 滑板场地施工_极限运动场地设计_滑板公园建造_盐城天人极限运动场地建设有限公司 | 杭州荣奥家具有限公司-浙江办公家具,杭州办公家具厂 | SDG吸附剂,SDG酸气吸附剂,干式酸性气体吸收剂生产厂家,超过20年生产使用经验。 - 富莱尔环保设备公司(原名天津市武清县环保设备厂) | 商用绞肉机-熟肉切片机-冻肉切丁机-猪肉开条机 - 广州市正盈机械设备有限公司 | 自动化生产线-自动化装配线-直流电机自动化生产线-东莞市慧百自动化有限公司 | 紧急切断阀_气动切断阀_不锈钢阀门_截止阀_球阀_蝶阀_闸阀-上海上兆阀门制造有限公司 | 施工电梯_齿条货梯_烟囱电梯_物料提升机-河南大诚机械制造有限公司 | 3A别墅漆/3A环保漆_广东美涂士建材股份有限公司【官网】 | 皮带机_移动皮带机_大倾角皮带机_皮带机厂家 - 新乡市国盛机械设备有限公司 | 展厅设计-展馆设计-专业企业展厅展馆设计公司-昆明华文创意 | 自恢复保险丝_贴片保险丝_力特保险丝_Littelfuse_可恢复保险丝供应商-秦晋电子 | 冷却塔改造厂家_不锈钢冷却塔_玻璃钢冷却塔改造维修-广东特菱节能空调设备有限公司 | 合肥通道闸-安徽车牌识别-人脸识别系统厂家-安徽熵控智能技术有限公司 | 精密机械零件加工_CNC加工_精密加工_数控车床加工_精密机械加工_机械零部件加工厂 | 矿用履带式平板车|探水钻机|气动架柱式钻机|架柱式液压回转钻机|履带式钻机-启睿探水钻机厂家 | 卓能JOINTLEAN端子连接器厂家-专业提供PCB接线端子|轨道式端子|重载连接器|欧式连接器等电气连接产品和服务 | 螺旋绞龙叶片,螺旋输送机厂家,山东螺旋输送机-淄博长江机械制造有限公司 | 陶瓷加热器,履带式加热器-吴江市兴达电热设备厂 | 鑫铭东办公家具一站式定制采购-深圳办公家具厂家直销 | 探鸣起名网-品牌起名-英文商标起名-公司命名-企业取名包满意 | 电地暖-电采暖-发热膜-石墨烯电热膜品牌加盟-暖季地暖厂家 | 大_小鼠elisa试剂盒-植物_人Elisa试剂盒-PCR荧光定量试剂盒-上海一研生物科技有限公司 | hc22_hc22价格_hc22哈氏合金—东锜特殊钢 | 手持式浮游菌采样器-全排二级生物安全柜-浙江孚夏医疗科技有限公司 | 玻璃瓶厂家_酱菜瓶厂家_饮料瓶厂家_酒瓶厂家_玻璃杯厂家_徐州东明玻璃制品有限公司 | 【化妆品备案】进口化妆品备案流程-深圳美尚美化妆品有限公司 |