SpringBoot熱部署簡介


首先來看看 JAVA 熱部署與熱加載的聯系:

  1. 都可以不重啟服務器的情況下進行編譯/部署項目;

  2. 基於 Java 的類加載器實現

熱部署與熱加載的區別:

  • 熱部署在服務器運行時重新部署項目
  • 熱加載在運行時重新加載 class (字節碼文件)
    只加載重新修改后的類(class 文件)
  • 熱部署會重新加載整個應用
  • 熱加載在運行時重新加載 class
    可以理解為 JVM 啟動后會啟動一個后台線程,定時來監控文件的時間戳,如果變化就將類重新載入
  • 熱部署更多在生產環境下使用,熱加載多在開發環境下使用(熱加載無法記錄“熱加載執行的日志”)

下面再來說一下 JVM 加載類的相關知識點,字節碼文件肯定是通過類加載器進行加載的,類加載一般可分為五個階段:

  1. 加載
    找到類的靜態存儲結構,加載到虛擬機里然后轉化成方法區運行時的數據結構,生成 class 對象;
    允許用戶自定義類加載器參與進來
  2. 驗證
    確保字節碼是安全的,不會對虛擬機造成危害,可以通過啟動參數來禁用一些驗證(不推薦)
  3. 准備
    確定內存布局,初始化類變量(給變量賦初始值不會執行程序自定義的賦值操作)
  4. 解析
    將符號引用轉換為直接引用
  5. 初始化
    這里才是調用程序自定義的初始化代碼

關於初始化階段,Java 規定在遇到五個時機時立即進行初始化(當然前面的步驟已經執行完了的情況下),需要注意的點有:

  • 遇到了 new、get、static 這幾個字節碼指令時如果類沒有初始化,則需要觸發初始化。
  • final 修飾的類會在編譯時把結果放到常量池中,即使調用也不會觸發初始化。畢竟 final 關鍵字它修飾的是常量。
  • 使用反射對類進行反射調用,如果類沒有進行初始化,就需要先初始化。
  • 當初始化一個類的時候,如果發現其父類還沒有進行過初始化,需要先觸發父類的初始化。
    也就是先初始化父類,再初始化子類。
  • 虛擬機啟動的時候用戶需要制定一個要執行的主類,虛擬機會先初始化這個主類。
  • 使用 jdk1.7 動態機制相關的句柄會進行初始化。

Java 類加載器的特點:

  • 由 APPClass Loader (系統類加載器)開始加載指定的類。
  • 類加載器將加載任務交給其父,如果其父找不到,再由自己去加載。
  • BootStrap Loader (啟動類加載器)是最頂級的類加載器,也就是說他的父加載器為空。

Java 類的熱部署可分為 類的熱加載 和 配置 Tomcat 的方式,配置 Tomcat 應該很熟悉了,關於類的熱加載相關代碼參考:

// 自定義的類加載器 public class MyClassLoader extends ClassLoader{ private String path; public MyClassLoader(String path){ super(ClassLoader.getSystemClassLoader()); this.path = path; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException{ System.out.println("加載類....."); byte[] data = loadClassData(name); return this.defineClass(name,data,0,data.length); } // 加載 Class 文件中的內容 private byte[] loadClassData(String name){ try{ name = name.replace(".", "//"); FileInputStream is = new FileInputStream(new File(path + name + ".class")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b = 0; while((b = is.read()) != -1){ baos.write(b); } is.close(); return baos.toByteArray(); }catch(Exception e){ e.printStackTrace(); } return null; } }

對於Tomcat 直接把項目放到 webapps 目錄里就會自動加載;server.xml 里的 host 添加 context

SpringBoot

使用 SpringBoot 進行熱部署總體來說有兩種方式,

一種是使用 springloaded(依賴配置在 build 中的 spring-boot-maven-plugin 插件中),必須要使用 mvn spring-boot:run 來允許才有效果,或者下載這個 jar 在 JVM 的啟動參數里配置。

第二種就比較簡單了,直接和平常一樣加入一個 devtools 依賴就可以了:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>

是的,就是這么簡單,推薦使用第二種

發布

SpringBoot 項目可以使用 jar 包來直接運行,也可以發布為 war 丟到 tomcat 里去允許,

第一種就不用多說了,運行 maven 的 install 后,直接命令行啟動就行:java -jar xxx.jar

第二種,首先打包方式改為 war 包,然后增加一個,然后在 application 入口類繼承 SpringBootServletInitializer,復寫 configure 方法:

// @SpringBootApplication:Spring Boot項目的核心注解,主要目的是開啟自動配置 @SpringBootApplication public class FirstSpringBootApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder){ return builder.sources(FirstSpringBootApplication.class); } public static void main(String[] args) { // 啟動 SpringBoot 所必須的入口 SpringApplication.run(FirstSpringBootApplication.class, args); } }

需要加入的依賴,SpringBoot 中加依賴不需要指定版本,在父工程已經設置好了,並且名稱都是 spring-boot-* :

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency>

然后執行 maven install 得到 war 包就可以了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM