2023-07-31 10:27:38來源:京東云開發(fā)者社區(qū) 責(zé)任編輯:武曉燕
開發(fā)者在編碼效率和快速迭代中的痛點(diǎn)場景包括:
1. 修改代碼后,需要頻繁重啟應(yīng)用,導(dǎo)致開發(fā)效率低下;
【資料圖】
2. 實(shí)時(shí)調(diào)試時(shí),不能立即看到代碼修改的結(jié)果;
3. 大型項(xiàng)目中,重啟的時(shí)間成本較高。
針對這些問題,本文將深入探討如何利用Spring Loaded熱更新技術(shù)提高開發(fā)效率,減少編譯和重啟時(shí)間。分析Spring Loaded的熱更新原理,以及實(shí)際應(yīng)用過程中所需的操作和注意事項(xiàng)。
2、框架簡介Spring Loaded is a JVM agent for reloading class file changes whilst a JVM is running. It transforms classes at loadtime to make them amenable to later reloading. Unlike "hot code replace" which only allows simple changes once a JVM is running (e.g. changes to method bodies),Spring Loaded allows you to add/modify/delete methods/fields/constructors. The annotations on types/methods/fields/constructors can also be modified and it is possible to add/remove/change values in enum types.
Spring Loaded 是一個 JVM 代理,可以在 JVM 運(yùn)行時(shí)重新加載類文件的更改。它會在加載時(shí)轉(zhuǎn)換類,以便稍后重新加載。與“熱代碼替換”只允許在 JVM 運(yùn)行時(shí)進(jìn)行簡單更改(例如更改方法體)不同,Spring Loaded 允許您添加/修改/刪除方法/字段/構(gòu)造函數(shù)。還可以修改類型/方法/字段/構(gòu)造函數(shù)上的注解,并且可以添加/刪除/更改枚舉類型中的值。
3、如何使用3.1 下載Agent插件https://repo1.maven.org/maven2/org/springframework/springloaded/1.2.8.RELEASE/springloaded-1.2.8.RELEASE.jar
3.2 引入Agent插件在jvm的啟動命令中添加以下參數(shù)
-javaagent:/Users/you/runtime/springloaded-1.2.8.RELEASE.jar -noverify
3.3 修改并重新編譯修改代碼后執(zhí)行Build->Recompile命令,可以看到在class reloaded完成后,程序的運(yùn)行邏輯發(fā)生了變化
4、原理分析4.1 代碼編譯分析先來看一段源代碼,這是一個RpcService類,定義了target字段、targetStatic靜態(tài)字段和say方法,現(xiàn)在我們編譯它。
public class RpcService { private String target = "rpc"; private static String targetStatic = "rpc static"; public String say() { return "RpcService say hello SpringLoaded" + target; }}
SpringLoaded對類編譯后添加了一些跟蹤記錄字段,添加方法攔截判斷。
public static ReloadableType r$type = TypeRegistry.getReloadableType(0, 1);public transient ISMgr r$fields;public static final SSMgr r$sfields;public String hello() { if (r$type.changed(0) == 1) { return r$type.fetchLatest()).say(this); } String targetNew = TypeRegistry.instanceFieldInterceptionRequired(1, "target") ? (String)r$get(this, "target") : this.target; return "RpcService say hello SpringLoaded" + targetNew;}
我們可以在代碼運(yùn)行時(shí),使用getDeclaredField、getDeclaredMethod等函數(shù)在運(yùn)行時(shí)獲取類成員、方法信息,此時(shí)可以看到增強(qiáng)后的類多了如下字段和方法。
在編譯后的代碼中,我們可以看到RpcService類包含了一些新的字段和方法,這些都是Spring Loaded框架增加的。
?r$type是一個靜態(tài)變量,其類型為ReloadableType。這個字段用于表示當(dāng)前類的可重載類型,它包含了當(dāng)前類的最新字節(jié)碼和其他相關(guān)信息。
r$get、r$set方法是用于獲取實(shí)例字段的值的方法,處理字段的攔截和替換。___clinit___方法是用于執(zhí)行類的靜態(tài)初始化塊的方法。___init___()方法是用于處理類的構(gòu)造函數(shù)的方法。在say()方法中增加了一個代碼片段用于判斷類是否發(fā)生了變更,如果變更了,則調(diào)用最新的可重載類型中的say()方法獲取結(jié)果。否則,繼續(xù)執(zhí)行原有的方法體。在方法體中,也增加了一個代碼片段用于判斷本地變量是否需要攔截,如果需要,則使用r$get()方法獲取非靜態(tài)變量traget的值,并用它替換原有的變量值。4.2 運(yùn)行過程分析1、在應(yīng)用程序啟動時(shí),Spring Loaded在目標(biāo)類路徑中查找所有的類,并在ClassPreProcessor中使用自定義類加載器加載這些類,重新定義后存入TypeRegistry,用于緩存、變更對比和依賴關(guān)系維護(hù)。
2、注冊一個文件變化監(jiān)聽器FileChangeListener,當(dāng)一個類文件被修改后,Spring Loaded會檢測到這個變化,并重新加載該類文件。
3、當(dāng)一個類被重新加載時(shí),Spring Loaded會嘗試對比類的簽名和繼承關(guān)系沒有改變,如果新的類定義與之前的類定義兼容,那么Spring Loaded會更新應(yīng)用程序中的對象引用,以指向新的類定義。
5、總結(jié)Spring-loaded 使用 Java 的 Instrumentation API 在 JVM 啟動時(shí)指定 Agent,使它能夠在目標(biāo)類加載之前進(jìn)行攔截,并將目標(biāo)類的字節(jié)碼通過 ASM 庫解析成抽象語法樹(AST),然后對 AST 進(jìn)行修改。修改的內(nèi)容包括增加、刪除、替換方法,修改方法體,添加字段等,最終替換目標(biāo)類,改變其邏輯,實(shí)現(xiàn)對代碼的熱更新。
6、擴(kuò)展內(nèi)容Jrebel也可以實(shí)現(xiàn)類似熱更新功能,并且它更高效、穩(wěn)定。jrebel官網(wǎng)Spring-boot-devtools也可以提升開發(fā)速度,但是它的方案更像是熱重啟。Spring Boot Devtools Restarter 原理如何自己實(shí)現(xiàn)一個熱更新功能呢?思路大同小異,實(shí)現(xiàn)各有千秋。如何自己實(shí)現(xiàn)一個熱加載?如何定義自己的類加載器?作者:京東零售 程嘯
來源:京東云開發(fā)者社區(qū)
關(guān)鍵詞:
1、引言開發(fā)者在編碼效率和快速迭代中的痛點(diǎn)場景包括:1 修改代碼后,
碼農(nóng)AI神器又升級了!就在剛剛,Github官宣,Copilot模型升級,5年內(nèi)80
峰值內(nèi)存消耗是訓(xùn)練深度學(xué)習(xí)模型(如視覺Transformer和LLM)時(shí)的常見瓶
連接的未來即將到來,它被稱為5G固定無線接入(FWA)。這項(xiàng)革命性的技術(shù)
了解2023年物聯(lián)網(wǎng)與邊緣計(jì)算之間的區(qū)別。在數(shù)字化轉(zhuǎn)型時(shí)代,物聯(lián)網(wǎng)(IoT
夏季治安打擊整治行動開展以來,省森林公安局明確任務(wù)目標(biāo),對林區(qū)森林
這些年內(nèi)虧損較高的百億基金,重倉股主要集中在鋰電池、光伏、汽車、醫(yī)
巴媒:巴基斯坦西北部爆炸事件已致44人死亡上百人受傷---據(jù)巴基斯坦《
山海關(guān)中國長城博物館正式定名
導(dǎo)讀1、俠嵐我也喜歡看,是一部動畫連續(xù)劇。2、故事情節(jié)和修真差不多,
寶駿云朵開啟盲訂將8月10日上市標(biāo)配雙大屏,寶駿汽車,新車,內(nèi)飾,五菱汽
近期天氣不平靜,臺風(fēng)一個接著一個!“杜蘇芮”已于昨天停止編號,但“
進(jìn)入7月份以來,A股市場分拆上市不斷傳來新消息?!蹲C券日報(bào)》記者據(jù)巨
中超第19輪,山東泰山3-0完勝北京國安。李源一傳射,費(fèi)萊尼、費(fèi)南多破
聊聊一篇小如,對于朱小如簡單介紹的文章,網(wǎng)友們對這件事情都比較關(guān)注