專利名稱:一種動(dòng)態(tài)替換類中字段的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及程序開發(fā)領(lǐng)域,特別是涉及一種動(dòng)態(tài)替換類中字段的方法。
背景技術(shù):
在實(shí)際Java程序開發(fā)中,Java程序開發(fā)者須經(jīng)常對(duì)代碼進(jìn)行反復(fù)修改測試,而每次的修改測試需要重建構(gòu)件部署整個(gè)應(yīng)用系統(tǒng),從而耗費(fèi)大量時(shí)間在等待中。若開發(fā)者無需重新構(gòu)件部署整個(gè)應(yīng)用系統(tǒng),只需將修改過的類重新編譯替換原系統(tǒng)中的類文件即可,而類文件替換的工作在大多數(shù)開發(fā)環(huán)境下可以快速自動(dòng)完成。這樣開發(fā)者就無需花費(fèi)大量的等待時(shí)間,從而顯著提高開發(fā)效率。解決該問題的關(guān)鍵之一在于,如何才能在不重啟JVM(Java Virtual Machine, Java虛擬機(jī))的前提下將現(xiàn)有的Java類中的字段修改后動(dòng)態(tài)進(jìn)行替換。
通常,針對(duì)類中字段動(dòng)態(tài)替換的問題,現(xiàn)有技術(shù)中已有一些解決方案,如一種方案是利用Java ClassLoader,該方案利用的是Java ClassLoader對(duì)類的加載機(jī)制,自己編寫設(shè)計(jì)一個(gè)針對(duì)系統(tǒng)的ClassLoader,使其當(dāng)有需要的時(shí)候,利用ClassLoader可以重新加載修改后的類文件。但這種方案的缺點(diǎn)是需要開發(fā)者額外自行設(shè)計(jì)一套適合其程序系統(tǒng)的類加載文件,可能這原本并不是需要考慮開發(fā)的,無疑增加了開發(fā)者的工作量,降低了開發(fā)效率,而且這種利用Java ClassLoader對(duì)類動(dòng)態(tài)替換的機(jī)制,也只能是對(duì)特定的類有效。另一種方案是利用JVM HotSwap,該方案是利用JVM的DebuggerAPI,從而允許通過調(diào)用這些API對(duì)類的字節(jié)碼(ByteCode)進(jìn)行替換。但其缺點(diǎn)是首先,程序必須在debug模式下運(yùn)行,這可能會(huì)給程序帶來很多不必要的問題;其次,其只允許對(duì)方法體內(nèi)的代碼進(jìn)行修改,不允許添加任何方法、字段,以及其他的任何操作,使得修改的范圍比較局限。再一種方案是利用其他特制的JVM,該方案利用Java程序是在一個(gè)虛擬機(jī)中運(yùn)行的,對(duì)于Java程序來說,并不關(guān)心具體在什么虛擬機(jī)上運(yùn)行,所以可以實(shí)現(xiàn)一個(gè)Java虛擬機(jī)使得其附有類動(dòng)態(tài)替換的功能。其缺點(diǎn)是利用特制的JVM的方案,會(huì)存在穩(wěn)定性、兼容性以及效率上的各種問題,除非主流的JVM在設(shè)計(jì)上進(jìn)行改革,使得其在兼容各方面的情況下,附有類動(dòng)態(tài)替換的功能,否則使用該方案還是存在較多風(fēng)險(xiǎn)。因此有必要提出一種新的技術(shù)方案來解決上述問題。
發(fā)明內(nèi)容
本部分的目的在于概述本發(fā)明的實(shí)施例的一些方面以及簡要介紹一些較佳實(shí)施例。在本部分以及本申請(qǐng)的說明書摘要和發(fā)明名稱中可能會(huì)做些簡化或省略以避免使本部分、說明書摘要和發(fā)明名稱的目的模糊,而這種簡化或省略不能用于限制本發(fā)明的范圍。本發(fā)明的目的在于提供一種動(dòng)態(tài)替換類中字段的方法,其可以在不重啟JVM的情況下動(dòng)態(tài)更改類中字段,顯著提高開發(fā)效率。為實(shí)現(xiàn)上述目的,本發(fā)明提供一種動(dòng)態(tài)替換類中字段的方法,其包括啟動(dòng)JVM,加載一個(gè)新的類,判斷該類是否為第一次被載入;
若所述類被第一次載入,則在全局信息表中注冊(cè)該類中所有字段信息;用一字段信息類字段代替該類中的所有字段信息并對(duì)其初始化;利用該類中的方法信息生成一抽象類,并在該類中定義一該抽象類類型的字段;根據(jù)該類中的方法信息和所述抽象類生成所述抽象類的一具體實(shí)現(xiàn)類,將該類中任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,均改為調(diào)用該類中字段信息類的獲取字段方法或修改字段方法,對(duì)類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改為調(diào)用該類中所述抽象類類型字段對(duì)應(yīng)的方法;檢測該類是否被動(dòng)態(tài)更新,若該類被動(dòng)態(tài)更新則使用動(dòng)態(tài)更新前的最后一抽象類的具體實(shí)現(xiàn)類將其初始化;和否則,在全局信息表中檢測更新其字段的信息;利用該類中的方法信息以及該類在第一載入時(shí)生成的抽象類生成所述抽象類的一個(gè)具體實(shí)現(xiàn)類,將該類中任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,均改為調(diào)用該類中字段信息類的獲取字段方法或修改字段方法,對(duì)類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改為調(diào)用該類中所述抽象類類型字段對(duì)應(yīng)的方法。進(jìn)一步的,啟動(dòng)JVM時(shí)還包括加載一動(dòng)態(tài)鏈接庫,所述動(dòng)態(tài)鏈接庫包括接口和內(nèi)部函數(shù),且利用接口調(diào)用內(nèi)部的函數(shù)以對(duì)所述類、抽象類以及具體實(shí)現(xiàn)類進(jìn)行處理。
進(jìn)一步的,加載一個(gè)新的類,包括在0]^88 File Load Hook事件被觸發(fā)后加載一個(gè)新的類。進(jìn)一步的,判斷該類是否為第一次被載入,包括分析所述被加載的類的字節(jié)碼,根據(jù)全局信息表檢查該類的ClassLoader以判斷該類是否被第一次載入。進(jìn)一步的,在全局信息表中注冊(cè)類中所有字段信息,包括根據(jù)該類中的所有字段,并用該類的ClassLoader以及該類的簽名,在全局信息表中注冊(cè)該類中所有字段信息,以表明該類被增強(qiáng)。進(jìn)一步的,用一字段信息類字段代替該類中的所有字段信息并對(duì)其初始化,包括將所述類中的所有字段均提取出來,用一字段信息類字段來代替,添加一靜態(tài)初始化塊,利用所提取出來的字段信息對(duì)所述自定義的字段信息類字段進(jìn)行初始化。更進(jìn)一步的,所述字段信息類字段包含一哈希表、所述獲取字段方法和所述修改字段方法。更進(jìn)一步的,所述獲取字段方法包括從全局信息表中查詢?cè)揅lassLoader下該類的所有字段信息,以判斷所述字段信息中是否包含該字段,若不包含則產(chǎn)生一個(gè)無該字段的異常;若需要獲取的該字段為靜態(tài)字段信息,則從全局信息表中查詢?cè)揅lassLoader下該類的該增強(qiáng)類字段的值,并以一 Object返回;若需要獲取的該字段為非靜態(tài)字段信息,則從本信息類中的hash表中獲取該增強(qiáng)類字段的信息,并以一 Object返回。更進(jìn)一步的,所述修改字段方法包括從全局信息表中查詢?cè)擃惣虞d下該類的最新字段信息,以判斷最新字段信息中是否包含該字段,若不包含則產(chǎn)生一個(gè)無該字段的異常,若該字段為不允許修改的,產(chǎn)生一個(gè)不允許修改的異常;若需要修改的字段為靜態(tài)字段,則從全局信息表中設(shè)置該類加載下該類的該字段的值;若需要修改的字段為非靜態(tài)字段,則從本信息類中的哈希表中修改該字段的值。進(jìn)一步的,所述抽象類中包含所述類中所有的方法,且抽象類中的所述方法均為抽象方法。與現(xiàn)有技術(shù)相比,本發(fā)明使用JVMTI (JVM Tool Interface)中一個(gè)特定事件ClassFile Load Hook,該事件會(huì)在JVM獲得一個(gè)類數(shù)據(jù)文件后,但在將其構(gòu)建成一個(gè)類放到內(nèi)存中前調(diào)用,在該事件觸發(fā)的函數(shù)中,可以對(duì)該類文件的字節(jié)碼進(jìn)行任意改動(dòng)。本發(fā)明主要就是從該事件被觸發(fā)后介入,對(duì)類文件進(jìn)行修改增強(qiáng),從而實(shí)現(xiàn)在無需要重啟應(yīng)用系統(tǒng)的情況下,將對(duì)類中字段有過任何改動(dòng)的類,以及類中現(xiàn)有方法體有過任何改動(dòng)的類進(jìn)行動(dòng)態(tài)替換。
為了更清楚地說明本發(fā)明實(shí)施例的技術(shù)方案,下面將對(duì)實(shí)施例描述中所需要使用的附圖作簡單地介紹,顯而易見地,下面描述中的附圖僅僅是本發(fā)明的一些實(shí)施例,對(duì)于本領(lǐng)域普通技術(shù)人員來講,在不付出創(chuàng)造性勞動(dòng)性的前提下,還可以根據(jù)這些附圖獲得其它的附圖。其中圖I為本發(fā)明中動(dòng)態(tài)替換類中字段的方法的流程圖;和
圖2為本發(fā)明中類被第一次載入后其字段被動(dòng)態(tài)替換的方法流程圖。
具體實(shí)施例方式本發(fā)明的詳細(xì)描述主要通過邏輯塊或其他概括性的描述來直接或間接地表述了本發(fā)明技術(shù)方案的運(yùn)作。為透徹的理解本發(fā)明,在接下來的描述中陳述了很多特定細(xì)節(jié)。而在沒有這些特定細(xì)節(jié)時(shí),本發(fā)明則可能仍可實(shí)現(xiàn)。此處的這些描述和陳述主要是為了向所屬領(lǐng)域內(nèi)的其他技術(shù)人員有效的介紹本發(fā)明技術(shù)方案的本質(zhì)。換句話說,為避免混淆本發(fā)明的目的,由于熟知的方法和程序已經(jīng)容易理解,因此它們并未被詳細(xì)描述。此處所稱的“一個(gè)實(shí)施例”或“實(shí)施例”是指可包含于本發(fā)明至少一個(gè)實(shí)現(xiàn)方式中的特定特征、結(jié)構(gòu)或特性。在本說明書中不同地方出現(xiàn)的“在一個(gè)實(shí)施例中”并非均指同一個(gè)實(shí)施例,也不是單獨(dú)的或選擇性的與其他實(shí)施例互相排斥的實(shí)施例。此外,表示一個(gè)或多個(gè)實(shí)施例的功能框圖中的模塊順序并非固定的指代任何特定順序,也不構(gòu)成對(duì)本發(fā)明的限制。通常,使用JVMTI (JVM Tool Interface)中一個(gè)特定事件Class File Load Hook,該事件會(huì)在JVM獲得一個(gè)類數(shù)據(jù)文件后,但在將其構(gòu)建成一個(gè)類放到內(nèi)存中前調(diào)用,在該事件觸發(fā)的函數(shù)中,可以對(duì)該類文件的字節(jié)碼進(jìn)行任意改動(dòng)。本發(fā)明主要就是從該事件被觸發(fā)后介入,對(duì)類文件進(jìn)行修改增強(qiáng),從而實(shí)現(xiàn)在無需要重啟應(yīng)用系統(tǒng)的情況下,將對(duì)類中字段有過任何改動(dòng)的類,以及類中現(xiàn)有方法體有過任何改動(dòng)的類進(jìn)行動(dòng)態(tài)替換。本發(fā)明提供的一種動(dòng)態(tài)替換類中字段的方法,其將一個(gè)類的方法和字段信息拆分來維護(hù)處理,且用一個(gè)抽象類的實(shí)現(xiàn)來完成類中方法體的修改更新。其具體過程可參見圖I所示。圖I為本發(fā)明中動(dòng)態(tài)替換類中字段的方法流程圖,其方法包括步驟110,啟動(dòng)JVM,加載一個(gè)特定的agentlib來實(shí)現(xiàn)對(duì)JVMTI事件的處理。這里所述的agentlib相當(dāng)于一個(gè)動(dòng)態(tài)鏈接庫,在一個(gè)實(shí)施例中,所述agentlib可以包括接口和事件等,當(dāng)不同的事件被觸發(fā)后,其可以通過接口調(diào)用內(nèi)部中對(duì)應(yīng)的函數(shù),下述中對(duì)類的修改(包括抽象類的生成以及抽象類的具體實(shí)現(xiàn)類的生產(chǎn)等)均在所述agentlib中進(jìn)行的。通常,在具體實(shí)現(xiàn)時(shí)其內(nèi)部還可以包含一個(gè)全局信息表,所述全局信息表中標(biāo)注了各個(gè)類是否被加載以及是否被第一次加載等信息。步驟120,在Class File Load Hook事件被觸發(fā)后,有一個(gè)新的類被裝載。—般的,所述Class File Load Hook事件在接收到消息后會(huì)將一個(gè)新的類載入到主程序中。步驟130,分析該類的字節(jié)碼(ByteCode),根據(jù)全局信息表,檢測是否為該ClassLoader第一次載入該類,如果是,則執(zhí)行步驟140 ;否則,執(zhí)行步驟150?!愕?,當(dāng)運(yùn)行Java程序時(shí),首先運(yùn)行JVM,然后再把Java class加載到JVM中運(yùn)行,負(fù)載加載Java class的這部分就叫做ClassLoader。所述全局信息表包含在所述加載的特定的agentlib中,其相當(dāng)于一個(gè)數(shù)據(jù)庫,內(nèi)部標(biāo)注了各個(gè)類是否被加載以及類是否被第一次加載等信息。這樣根據(jù)所述全局信息表可以檢測出為ClassLoader載入的類是否為第一次載入。
步驟140,如果所述類屬于需要?jiǎng)討B(tài)替換的類,則實(shí)現(xiàn)對(duì)所述類中字段進(jìn)行動(dòng)態(tài)替換,流程結(jié)束。其中,對(duì)所述類中字段進(jìn)行動(dòng)態(tài)替換的具體過程可參見圖2所示。圖2本發(fā)明中類被第一次載入后其字段被動(dòng)態(tài)替換的方法流程圖,其方法包括步驟1401,用該類的ClassLoader和該類的簽名,并在分析該類中的所有字段后,在全局信息表中注冊(cè)其字段的信息以表明該類被增強(qiáng)。步驟1402,將該類中的所有字段均提取出來,用一個(gè)自定義的字段信息類字段(_fieldj來代替。步驟1403,添加一靜態(tài)初始化塊(Static Initialization Blocks),利用提取出來的字段信息對(duì)所述自定義的字段信息類字段做初始化。在具體實(shí)現(xiàn)時(shí),所述字段類信息字段_打61(1_包含一哈希(hash)表、一獲取字段方法(getfield)和一修改字段方法(setfield)等信息。步驟1404,利用該類中的方法信息,生成一個(gè)抽象類(abstract class),并在該類中添加一個(gè)該抽象類類型的字段(_method_)。其中,生成的所述抽象類中包含原類中所有的方法,但抽象類中的所述方法只是抽象方法。由于在處理的過程中,所述原有類的每個(gè)實(shí)例可能需要?jiǎng)?chuàng)建不同的對(duì)象,如果反復(fù)創(chuàng)建類和方法會(huì)很繁瑣和麻煩,所以這里利用原有類中的方法信息創(chuàng)建一個(gè)抽象類。這樣通過抽象類生成不同的具體實(shí)現(xiàn)類以實(shí)現(xiàn)不同的實(shí)例。這樣,由抽象類的特性可知,在對(duì)原有類進(jìn)行具體實(shí)現(xiàn)時(shí),無需改變?cè)蓄愔械娜魏螖?shù)據(jù),而只需要利用抽象類。步驟1405,利用該類中的方法信息、所述生成的抽象類以生成一個(gè)所述抽象類的具體實(shí)現(xiàn)類,并將類中任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,均改為調(diào)用該類中字段信息類的獲取字段方法(getField)或修改字段方法(setField),并以需要讀取的字段的簽名為參數(shù),再根據(jù)實(shí)際情況做必要的類型轉(zhuǎn)換;對(duì)類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改為調(diào)用該類中所述抽象類類型字段_method_中對(duì)應(yīng)的方法。由上可知,這里對(duì)類中需要讀取或修改被增強(qiáng)類字段以及對(duì)增強(qiáng)類方法的調(diào)用方式的修改,均是在抽象類的具體實(shí)施類中進(jìn)行的,而非改變了原有類。在一個(gè)實(shí)施例中,當(dāng)對(duì)原有類A(即增強(qiáng)類)進(jìn)行掃描的過程中發(fā)現(xiàn)存在需要讀取或修改被增強(qiáng)類字段的調(diào)用,則直接利用自定義的getField方法來調(diào)用增強(qiáng)類字段。也就是說,當(dāng)原有類A中存在讀取或修改被增強(qiáng)類字段的調(diào)用時(shí)不再利用原有類A中的調(diào)用方式,而是改為自定義的一種getField方法來實(shí)現(xiàn)增強(qiáng)類字段的調(diào)用。在一個(gè)實(shí)施例中,所述獲取字段方法getField流程如下首先從所述全局信息表中查詢?cè)揅lassLoader下該類的最新字段信息,以確定所述最新字段信息中是否包含該被增強(qiáng)類字段,若不包含所述被增強(qiáng)類字段則產(chǎn)生一個(gè)無該字段的異常;若包含該被增強(qiáng)類字段,則進(jìn)一步判斷需要獲取的被增強(qiáng)類字段是否為靜態(tài)字段信息(Static Fields),若為靜態(tài)字段信息則從所述全局信息表中查詢所述ClassLoader下該類的該被增強(qiáng)類字段的值,并以一 Object返回;若需要獲取的被增強(qiáng)類字段為非靜態(tài)字段信息,則從本信息類中的hash表中獲取該字段的信息,并以一 Object返回。在另一個(gè)實(shí)施例中,所述修改字段方法setfield包括從所述全局信息表中查詢?cè)揅lassLoader下該類的最新字段信息,以確定所述最新字段信息中是否包含該被增強(qiáng)類字段,若不包含該被增強(qiáng)類字段則產(chǎn)生一個(gè)無該字段的異常,若該被增強(qiáng)類字段為不允許修改的字段,則產(chǎn)生一個(gè)不允許修改的異常;否則判定該被增強(qiáng)類字段是否為靜態(tài)字段,若需要修改的被增強(qiáng)類字段為靜態(tài)字段,則在所述全局信息表中設(shè)置該ClassLoader下該 類的該被增強(qiáng)類字段的值;若需要修改的被增強(qiáng)類字段為非靜態(tài)字段,則從本信息類中的hash表中修改該被增強(qiáng)類字段的值。其中hash表適用于保存原類中字段對(duì)應(yīng)的對(duì)象,其內(nèi)部的值與類中的字段信息是--映射的。也就是說如果在原有類中檢測到需要調(diào)用讀取或修改被增強(qiáng)類字段時(shí),不再利用原來的調(diào)用方式,而是調(diào)用自定義的getField或setField方式來實(shí)現(xiàn),從而可以實(shí)現(xiàn)動(dòng)態(tài)替換;或如果在掃描原有類中含有需要調(diào)用讀取或修改被增強(qiáng)類方法時(shí),也不再利用原來的調(diào)用方式,而是調(diào)用自定義的method中對(duì)應(yīng)的方法來實(shí)現(xiàn)動(dòng)態(tài)替換。步驟1406,添加一靜態(tài)初始?jí)K,根據(jù)一些必要的信息去檢查該類是否有被動(dòng)態(tài)更新,使用抽象類的最新具體實(shí)現(xiàn)類將其初始化,流程結(jié)束。所述必要的信息可以為全局信息表中的最新實(shí)現(xiàn)類標(biāo)識(shí)等。在一個(gè)實(shí)施例中,可以在該類中添加一靜態(tài)代碼,當(dāng)類實(shí)例化后則開始加載該類的ClassLoader,此時(shí)去檢查具體實(shí)施化后類中所述靜態(tài)代碼的變化,若發(fā)生變化則表明該類被動(dòng)態(tài)更新。上述僅舉出一種簡單的檢測類動(dòng)態(tài)更新的方法,通常檢查類是否有被動(dòng)態(tài)更新的技術(shù)是所屬領(lǐng)域的普通技術(shù)人員都能夠?qū)崿F(xiàn)的,所以這里就不再一一具體詳述。而最新的具體實(shí)現(xiàn)類可以理解為當(dāng)再次加載類時(shí),其類的實(shí)現(xiàn)類在初始化后得到具體實(shí)例化的類,其由原有類得到的所述抽象類也會(huì)被具體實(shí)例化,從而產(chǎn)生新的具體實(shí)現(xiàn)類。因此,當(dāng)檢查該類被動(dòng)態(tài)更新需要重新初始化時(shí),則將最新的也即為動(dòng)態(tài)更新前最后一抽象類的具體實(shí)現(xiàn)類來初始化該類。這里抽象類和抽象類的具體實(shí)現(xiàn)類的特點(diǎn)為現(xiàn)有的背景知識(shí),且不作為本發(fā)明的技術(shù)要點(diǎn),所以就不再詳述。步驟150,如果所述類屬于需要?jiǎng)討B(tài)替換的類,則分別實(shí)現(xiàn)對(duì)所述類中字段和方法體進(jìn)行動(dòng)態(tài)替換,流程結(jié)束;其中,分別實(shí)現(xiàn)對(duì)所述類中字段和方法體進(jìn)行動(dòng)態(tài)替換具體為利用該類的ClassLoader以及該類的簽名,且在分析該類中的所有字段后,在一個(gè)全局信息表中檢查更新其字段的信息;利用該類中的方法信息以及該類在第一次載入時(shí)生成的抽象類以生成一個(gè)所述抽象類的具體實(shí)現(xiàn)類,并將所述原始類中任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,均改為調(diào)用該類中字段信息類的getField或setField方法(具體參見上述描述),并以需要讀取的字段的簽名為參數(shù),再根據(jù)實(shí)際情況做必要的類型轉(zhuǎn)換;對(duì)類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改為調(diào)用該類中_method_中對(duì)應(yīng)的方法。其與所述類被第一次載入時(shí)處理的區(qū)別在于不再生成抽象類,而是利用上第一次載入時(shí)生成的抽象類以生成一具體實(shí)現(xiàn)類。綜上所述,本發(fā)明通過將一個(gè)類的方法和字段信息拆分開來維護(hù)處理,且用一個(gè)抽象類的實(shí)現(xiàn)來完成類中方法的修改更新,從Class文件的ByteCode的層面上來進(jìn)行加工改造,使得用戶可以無需額外開發(fā)編碼,既可在無需重啟應(yīng)用的前提下,對(duì)Java類的字段進(jìn)行任意的添加、刪除和修改,實(shí)現(xiàn)動(dòng)態(tài)替換,顯著提高開發(fā)效率,而且可以在通用的JVM上方便使用。上述說明已經(jīng)充分揭露了本發(fā)明的具體實(shí)施方式
。需要指出的是,熟悉該領(lǐng)域的技術(shù)人員對(duì)本發(fā)明的具體實(shí)施方式
所做的任何改動(dòng)均不脫離本發(fā)明的權(quán)利要求書的范圍。 相應(yīng)地,本發(fā)明的權(quán)利要求的范圍也并不僅僅局限于前述具體實(shí)施方式
。
權(quán)利要求
1.一種動(dòng)態(tài)替換類中字段的方法,其特征在于,其包括 啟動(dòng)JVM,加載一個(gè)新的類,判斷該類是否為第一次被載入; 若所述類被第一次載入,則在全局信息表中注冊(cè)該類中所有字段信息;用一字段信息類字段代替該類中的所有字段信息并對(duì)其初始化;利用該類中的方法信息生成一抽象類,并在該類中定義一該抽象類類型的字段;根據(jù)該類中的方法信息和所述抽象類生成所述抽象類的一具體實(shí)現(xiàn)類,將該類中任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,均改為調(diào)用該類中字段信息類的獲取字段方法或修改字段方法,對(duì)類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改為調(diào)用該類中所述抽象類類型字段對(duì)應(yīng)的方法;檢測該類是否被動(dòng)態(tài)更新,若該類被動(dòng)態(tài)更新則使用動(dòng)態(tài)更新前的最后一抽象類的具體實(shí)現(xiàn)類將其初始化; 否則,在全局信息表中檢測更新其字段的信息;利用該類中的方法信息以及該類在第一載入時(shí)生成的抽象類生成所述抽象類的一個(gè)具體實(shí)現(xiàn)類,將該類中任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,均改為調(diào)用該類中字段信息類的獲取字段方法或修改字段方法,對(duì)類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改為調(diào)用該類中所述抽象類類型字段對(duì)應(yīng)的方法。
2.根據(jù)權(quán)利要求I所述的方法,其特征在于啟動(dòng)JVM時(shí)還包括 加載一動(dòng)態(tài)鏈接庫,所述動(dòng)態(tài)鏈接庫包括接口和內(nèi)部函數(shù),且利用所述接口調(diào)用所述內(nèi)部函數(shù)以對(duì)所述類、抽象類以及具體實(shí)現(xiàn)類進(jìn)行處理。
3.根據(jù)權(quán)利要求I所述的方法,其特征在于加載一個(gè)新的類,包括 在Class File Load Hook事件被觸發(fā)后加載一個(gè)新的類。
4.根據(jù)權(quán)利要求I所述的方法,其特征在于判斷該類是否為第一次被載入,包括 分析所述被加載的類的字節(jié)碼,根據(jù)全局信息表檢查該類的ClassLoader以判斷該類是否被第一次載入。
5.根據(jù)權(quán)利要求I所述的方法,其特征在于在全局信息表中注冊(cè)該類中所有字段信息,包括 根據(jù)該類中的所有字段,并用該類的ClassLoader以及該類的簽名,在全局信息表中注冊(cè)該類中所有字段信息,以表明該類被增強(qiáng)。
6.根據(jù)權(quán)利要求I所述的方法,其特征在于用一字段信息類字段代替該類中的所有字段信息并對(duì)其初始化,包括 將所述類中的所有字段均提取出來,用一字段信息類字段來代替,添加一靜態(tài)初始化塊,利用所提取出來的字段信息對(duì)所述自定義的字段信息類字段進(jìn)行初始化。
7.根據(jù)權(quán)利要求6所述的方法,其特征在于所述字段信息類字段包含一哈希表、所述獲取字段方法和所述修改字段方法。
8.根據(jù)權(quán)利要求7所述的方法,其特征在于所述獲取字段方法包括 從全局信息表中查詢?cè)揅lassLoader下該類的所有字段信息,以判斷所述字段信息中是否包含該字段,若不包含則產(chǎn)生一個(gè)無該字段的異常; 若需要獲取的該字段為靜態(tài)字段信息,則從全局信息表中查詢?cè)揅lassLoader下該類的該增強(qiáng)類字段的值,并以一 Object返回; 若需要獲取的該字段為非靜態(tài)字段信息,則從本信息類中的哈希表中獲取該增強(qiáng)類字段的信息,并以一 Object返回。
9.根據(jù)權(quán)利要求7所述的方法,其特征在于所述修改字段方法包括 從全局信息表中查詢?cè)擃惣虞d下該類的最新字段信息,以判斷最新字段信息中是否包含該字段,若不包含則產(chǎn)生一個(gè)無該字段的異常,若該字段為不允許修改的,產(chǎn)生一個(gè)不允許修改的異常; 若需要修改的字段為靜態(tài)字段,則從全局信息表中設(shè)置該類加載下該類的該字段的值; 若需要修改的字段為非靜態(tài)字段,則從本信息類中的哈希表中修改該字段的值。
10.根據(jù)權(quán)利要求I所述的方法,其特征在于所述抽象類中包含所述類中所有的方法,且抽象類中的所述方法均為抽象方法。
全文摘要
本發(fā)明提供一種動(dòng)態(tài)替換類中字段的方法,屬于程序開發(fā)領(lǐng)域。所述方法通過原有類中的方法生成抽象類,并根據(jù)抽象類的具體實(shí)現(xiàn)類來實(shí)現(xiàn)原有類的實(shí)例化,當(dāng)檢測出原有類中的任何需要讀取或修改被增強(qiáng)類字段的調(diào)用,改變?yōu)樽远x的一種調(diào)用方式,當(dāng)檢測出原有類中任何需要調(diào)用被增強(qiáng)類方法的調(diào)用,均改變?yōu)樽远x的一種調(diào)用方式,從而實(shí)現(xiàn)在無需重啟JVM的情況下動(dòng)態(tài)替換類中的字段。
文檔編號(hào)G06F17/30GK102736905SQ20111009114
公開日2012年10月17日 申請(qǐng)日期2011年4月12日 優(yōu)先權(quán)日2011年4月12日
發(fā)明者劉鐘澤 申請(qǐng)人:深圳市金蝶中間件有限公司