Spring boot實(shí)現(xiàn)熱部署的兩種方式詳解
熱部署是什么
大家都知道在項(xiàng)目開發(fā)過程中,常常會(huì)改動(dòng)頁面數(shù)據(jù)或者修改數(shù)據(jù)結(jié)構(gòu),為了顯示改動(dòng)效果,往往需要重啟應(yīng)用查看改變效果,其實(shí)就是重新編譯生成了新的 Class 文件,這個(gè)文件里記錄著和代碼等對(duì)應(yīng)的各種信息,然后 Class 文件將被虛擬機(jī)的 ClassLoader 加載。
而熱部署正是利用了這個(gè)特點(diǎn),它監(jiān)聽到如果有 Class 文件改動(dòng)了,就會(huì)創(chuàng)建一個(gè)新的 ClaassLoader 進(jìn)行加載該文件,經(jīng)過一系列的過程,最終將結(jié)果呈現(xiàn)在我們眼前。
類加載機(jī)制
Java 中的類經(jīng)過編譯器可以把代碼編譯為存儲(chǔ)字節(jié)碼的 Class 文件,該 Class 文件存儲(chǔ)了各種信息,最終要加載到虛擬機(jī)中運(yùn)行使用。
類加載機(jī)制(摘自《深入理解 Java 虛擬機(jī)》)
虛擬機(jī)把描述類的數(shù)據(jù)從 Class 文件加載到內(nèi)存中,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機(jī)直接使用的 Java 類型。
Spring Boot 實(shí)現(xiàn)熱部署
Spring Boot 實(shí)現(xiàn)熱部署很簡(jiǎn)單,我們使用上一章創(chuàng)建的項(xiàng)目 Springboot 創(chuàng)建簡(jiǎn)單的 web 交互應(yīng)用 來演示。
- 使用 Spring Loaded
- 使用 spring-boot-devtools
springloaded
在 POM 文件中添加依賴
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.6.RELEASE</version> </dependency> </dependencies> </plugin> </plugins> </build>
添加完畢,啟動(dòng)項(xiàng)目
Note
這次啟動(dòng)不能直接運(yùn)行 main 方法了,需要使用
mvn spring-boot:run
啟動(dòng),然后隨意在代碼中寫一個(gè) System.out.println("Hi")
,再次調(diào)用那個(gè)方法,會(huì)發(fā)現(xiàn)控制臺(tái)會(huì)打印出 Hi。
spring-boot-devtools
添加 POM 文件依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <!-- 這個(gè)需要為 true 熱部署才有效 --> </dependency>
然后還是使用 mvn spring-boot:run 啟動(dòng)項(xiàng)目,隨意更改代碼即可看到效果。
如果我們想指定讓 devtools 監(jiān)聽指定文件夾,那么可以在 application.yml 配置
spring.devtools.restart.additional-paths=your path
,注意這里需要改成 yml 文件的格式。
Important(特別注意)
可能會(huì)有同學(xué)按照以上方法處理了都無效。
這里要特別注意下:由于熱部署是監(jiān)聽 Class 文件的變化,它自身不會(huì)主動(dòng)去編譯 Java 文件,所以我們得在 Java 文件改動(dòng)時(shí),自動(dòng)編譯成 Class 文件,然后熱部署工具創(chuàng)造的新的類加載器才會(huì)加載改變后的 Class 文件。
所以,如果你使用 IDEA 開發(fā)工具的話,記得要把自動(dòng)編譯打開。
如圖打鉤即可。
由于熱部署的時(shí)候是產(chǎn)生了新的類加載器,我們的一個(gè)類可能在虛擬機(jī)中存在兩個(gè)類,比如代碼中就一個(gè) User 類,但是虛擬機(jī)中會(huì)存在兩個(gè) User ,雖然是同一個(gè) Class 文件,但是卻是兩個(gè)獨(dú)立的類,這個(gè)要清楚。
由于第一次使用熱部署,一開始遇到個(gè)很奇怪的問題,A instanceof A == false
,明明兩個(gè) A.getClass()
都一樣,但結(jié)果就是 false,還問了幾個(gè)朋友,表示都沒遇到,后來當(dāng)我把 devtools 依賴注釋后,才正確執(zhí)行。
如果有遇到類似問題的朋友,可以檢查下是不是由于不同的 ClassLoader 造成的。
本系列所有代碼已同步到 GitHub, 項(xiàng)目地址 github:sboot-learn,大家也可以通過本地進(jìn)行下載。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Spring Cache自定義緩存key和過期時(shí)間的實(shí)現(xiàn)代碼
使用 Redis的客戶端 Spring Cache時(shí),會(huì)發(fā)現(xiàn)生成 key中會(huì)多出一個(gè)冒號(hào),而且有一個(gè)空節(jié)點(diǎn)的存在,查看源碼可知,這是因?yàn)?nbsp;Spring Cache默認(rèn)生成key的策略就是通過兩個(gè)冒號(hào)來拼接,本文給大家介紹了Spring Cache自定義緩存key和過期時(shí)間的實(shí)現(xiàn),需要的朋友可以參考下2024-05-05解析SpringSecurity+JWT認(rèn)證流程實(shí)現(xiàn)
這篇文章主要介紹了解析SpringSecurity+JWT認(rèn)證流程實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07java獲得平臺(tái)相關(guān)的行分隔符和java路徑分隔符的方法
不同系統(tǒng)平臺(tái)下的行分隔符、路徑分隔符等常常不同,如何在Java程序獲取當(dāng)前平臺(tái)的分隔符,以及其他系統(tǒng)相關(guān)的狀態(tài)呢?下面是示例程序,需要的朋友可以參考下2014-02-02Springcloud微服務(wù)架構(gòu)基礎(chǔ)知識(shí)解析
這篇文章主要介紹了Springcloud微服務(wù)架構(gòu)基礎(chǔ)知識(shí)解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04