ASM(動態(tài)增強)

ASM(動態(tài))

前面那篇是靜態(tài)修改字節(jié)碼的方式昔期,這種方式只是一種demo硼一,方便初學(xué)者進行學(xué)習(xí)基本的API操作,真正在線上環(huán)境有作用的是動態(tài)的去修改字節(jié)碼哼蛆。

例如一個進程正在運行著,這個時候我們需要在業(yè)務(wù)無感知的情況下進行打印日志叠洗,或者計算接口的操作時間這種操作,這個時候我們就需要動態(tài)的去操作JVM中的字節(jié)碼文件了

動態(tài)操作字節(jié)碼

動態(tài)操作字節(jié)碼的方式玉锌,其實還是主要使用agentmain禀倔,在javaagent的類attch到j(luò)vm上面的時候會調(diào)用這個方法執(zhí)行內(nèi)部的代碼邏輯。

如何使用

首先我們需要有一個agent鞋既,這個agent實現(xiàn)了agentmain的方法跌前,并且改寫對應(yīng)類的字節(jié)碼文件抵乓。DynamicPreMainAddTimeStatAgent

public class DynamicPreMainAddTimeStatAgent {


    public static void agentmain(String agentArgs, Instrumentation inst) throws Exception {
        System.out.println("Agent Main called");
        System.out.println("agentArgs:" + agentArgs);
        inst.addTransformer(new ClassFileTransformer() {
            public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
                System.out.println("load transform");

                if (className.equals("com/wsqandgy/asm/dynamic/Account")) {
                    System.out.println("meet com/wsqandgy/asm/dynamic/Account ");
                    /** classfileBuffer */
                    ClassReader classReader = new ClassReader(classfileBuffer);
                    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
                    TimeStatClassAdapter timeStatClassAdapter = new TimeStatClassAdapter(cw);
                    classReader.accept(timeStatClassAdapter, ClassReader.SKIP_DEBUG);
                    byte[] data = cw.toByteArray();
                    return data;
                } else {
                    System.out.println("load class:" + className);
                    System.out.println("new !");
                    return classfileBuffer;
                }
            }
        },true);
        System.out.println(Account.class.getClassLoader());
        inst.retransformClasses(Account.class);
    }
}

在上述操作中使用了TimeStatClassAdapter這個Class修改適配器和TimeStatMethodAdapter修改適配器蜈出。

增加TimeStat的方法,提供打印運行時間的方法煤杀。

public class TimeStat {
    static ThreadLocal<Long> t = new ThreadLocal<Long>();


    public static void start() {
        t.set(System.currentTimeMillis());
    }

    public static void end() {
        long time = System.currentTimeMillis();
        System.out.print(Thread.currentThread().getStackTrace()[2] + " spend:");
        System.out.println(time - t.get());
    }
}

針對上面的內(nèi)容創(chuàng)建MANIFEST.MF文件酌儒,并且進行打成jar包。

Manifest-Version: 1.0
Agent-Class: com.wsqandgy.asm.dynamic.DynamicPreMainAddTimeStatAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true

以上就是全部改寫字節(jié)碼文件的類和agentmain對應(yīng)方法的類文件了榴啸。眾所周知,我們需要對JVM進行注入就需要獲取到全部的JVM運行信息库说,Java提供了一個方法可以獲取到運行的JVM的相關(guān)信息。List<VirtualMachineDescriptor> list = VirtualMachine.list();

我們通過以上的方法獲取到對應(yīng)的JVM運行實例啰挪,進行attch操作抽活。

public class AttachToolMain {
    public static void main(String[] args) throws Exception {
        List<VirtualMachineDescriptor> list = VirtualMachine.list();
        for (VirtualMachineDescriptor machineDescriptor : list) {
            if (machineDescriptor.displayName().equals("com.wsqandgy.asm.dynamic.RunLoopAccountMain")) {
                VirtualMachine virtualMachine = VirtualMachine.attach(machineDescriptor.id());
                System.out.println(new File("/Users/gongyan/Documents/home_code/tools/classes/artifacts/dynamicTimeAgent/dynamicTimeAgent.jar").exists());
                virtualMachine.loadAgent("/Users/gongyan/Documents/home_code/tools/classes/artifacts/dynamicTimeAgent/dynamicTimeAgent.jar","argument for agent");
                System.out.println("attach ok!");
                virtualMachine.detach(); // 派遣操作歇由,意思為生效
            }
        }
    }
}

運行效果:

before

當我們運行AttachToolMain后,字節(jié)碼重新生成已經(jīng)增加了對應(yīng)的響應(yīng)時間了。

after
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市千劈,隨后出現(xiàn)的幾起案子墙牌,更是在濱河造成了極大的恐慌,老刑警劉巖虽风,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剥懒,死亡現(xiàn)場離奇詭異验游,居然都是意外死亡崔梗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門谈为,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伞鲫,“玉大人,你說我怎么就攤上這事吠架∷懈兀” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仑氛。 經(jīng)常有香客問我锯岖,道長,這世上最難降的妖魔是什么鸠珠? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任亲族,我火速辦了婚禮霎迫,結(jié)果婚禮上女气,老公的妹妹穿的比我還像新娘缘滥。我一直安慰自己,他們只是感情好赃阀,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著王凑,像睡著了一般聋丝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天宴倍,我揣著相機與錄音阔逼,去河邊找鬼嗜浮。 笑死危融,一個胖子當著我的面吹牛吉殃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播冶共,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼上荡,長吁一口氣:“原來是場噩夢啊……” “哼永罚!你這毒婦竟也來了卖陵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤看靠,失蹤者是張志新(化名)和其女友劉穎赶促,沒想到半個月后液肌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挟炬,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年嗦哆,在試婚紗的時候發(fā)現(xiàn)自己被綠了谤祖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡老速,死狀恐怖粥喜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情橘券,我是刑警寧澤额湘,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站旁舰,受9級特大地震影響锋华,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箭窜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一毯焕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磺樱,春花似錦纳猫、人聲如沸婆咸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尚骄。三九已至,卻和暖如春侵续,著一層夾襖步出監(jiān)牢的瞬間乖仇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工询兴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乃沙,地道東北人。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓诗舰,卻偏偏與公主長得像警儒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子眶根,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蜀铲,服務(wù)發(fā)現(xiàn),斷路器属百,智...
    卡卡羅2017閱讀 134,694評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,266評論 25 707
  • I【對關(guān)鍵詞的自身理解和體會】 黨和國家機構(gòu)職能體系是中國特色社會主義制度的重要組成部分记劝,是我們黨治國理政的...
    啦啦啦啊啊啊笑嘻嘻閱讀 254評論 0 0
  • 有這樣一個故事:或許是人為,或許是疏忽族扰,蚌突然某一天感到體內(nèi)多了一粒沙厌丑,很不舒服,它用盡力氣渔呵,費盡心機仍無法把沙子...
    秋天草莓閱讀 336評論 0 1
  • 001怎樣才能吃的更加健康怒竿,這個每天面臨各種疾病跟污染的社會,吃得健康已經(jīng)是我們面臨的一個非常重要的問題扩氢。 002...
    趙慧姿閱讀 328評論 2 1