Spring boot實現熱部署的兩種方式詳解
熱部署是什麼
大家都知道在專案開發過程中,常常會改動頁面資料或者修改資料結構,為了顯示改動效果,往往需要重啟應用檢視改變效果,其實就是重新編譯生成了新的 Class 檔案,這個檔案裡記錄著和程式碼等對應的各種資訊,然後 Class 檔案將被虛擬機器的 ClassLoader 載入。
而熱部署正是利用了這個特點,它監聽到如果有 Class 檔案改動了,就會建立一個新的 ClaassLoader 進行載入該檔案,經過一系列的過程,最終將結果呈現在我們眼前。
類載入機制
Java 中的類經過編譯器可以把程式碼編譯為儲存位元組碼的 Class 檔案,該 Class 檔案儲存了各種資訊,最終要載入到虛擬機器中執行使用。
類載入機制(摘自《深入理解 Java 虛擬機器》)
虛擬機器把描述類的資料從 Class 檔案載入到記憶體中,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的 Java 型別。
Spring Boot 實現熱部署
Spring Boot 實現熱部署很簡單,我們使用上一章建立的專案 Springboot 建立簡單的 web 互動應用 來演示。
- 使用 spring-boot-devtools
springloaded
在 POM 檔案中新增依賴
?123456789101112131415 | <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> |
新增完畢,啟動專案
Note
這次啟動不能直接執行 main 方法了,需要使用mvn spring-boot:run
啟動,然後隨意在程式碼中寫一個 System.out.println("Hi")
,再次呼叫那個方法,會發現控制檯會打印出 Hi。
spring-boot-devtools
新增 POM 檔案依賴
?12345 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional> true </optional> <!-- 這個需要為 true 熱部署才有效 --> </dependency> |
然後還是使用 mvn spring-boot:run 啟動專案,隨意更改程式碼即可看到效果。
如果我們想指定讓 devtools 監聽指定資料夾,那麼可以在 application.yml 配置spring.devtools.restart.additional-paths=your path
,注意這裡需要改成 yml 檔案的格式。
Important(特別注意)
可能會有同學按照以上方法處理了都無效。
這裡要特別注意下:由於熱部署是監聽 Class 檔案的變化,它自身不會主動去編譯 Java 檔案,所以我們得在 Java 檔案改動時,自動編譯成 Class 檔案,然後熱部署工具創造的新的類載入器才會載入改變後的 Class 檔案。
所以,如果你使用 IDEA 開發工具的話,記得要把自動編譯開啟。
如圖打鉤即可。
由於熱部署的時候是產生了新的類載入器,我們的一個類可能在虛擬機器中存在兩個類,比如程式碼中就一個 User 類,但是虛擬機器中會存在兩個 User ,雖然是同一個 Class 檔案,但是卻是兩個獨立的類,這個要清楚。
由於第一次使用熱部署,一開始遇到個很奇怪的問題,A instanceof A == false
,明明兩個 A.getClass()
都一樣,但結果就是 false,還問了幾個朋友,表示都沒遇到,後來當我把 devtools 依賴註釋後,才正確執行。
如果有遇到類似問題的朋友,可以檢查下是不是由於不同的 ClassLoader 造成的。
本系列所有程式碼已同步到 GitHub, 專案地址 github:sboot-learn,大家也可以通過本地進行下載。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對指令碼之家的支援。