1. 程式人生 > >spring boot之 DevTools 熱部署,修改程式碼立刻見效,快速重啟

spring boot之 DevTools 熱部署,修改程式碼立刻見效,快速重啟

IDEA新建sping boot選擇  DevTools

spring-boot-devtools 模組能夠實現熱部署,新增類  新增方法  修改配置檔案  修改頁面等 都能實現熱部署
    原理就是重啟專案,但比手動重啟快多了,其深層原理是使用了兩個ClassLoader,一個Classloader載入那些不會改變的類(第三方Jar包),另一個ClassLoader載入會更改的類,稱為  restart ClassLoader,這樣在有程式碼更改的時候,原來的restart ClassLoader 被丟棄,重新建立一個restart ClassLoader,由於需要載入的類相比較少,所以實現了較快的重啟時間(5秒以內)

第一步 引入jar+外掛
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>    不能被其它模組繼承,如果多個子模組可以去掉  不必須
           <scope>runtime</scope>     只在執行時起作用  打包時不打進去
</dependency>    
新增spring-boot-maven-plugin:
<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                      <!--fork :  如果沒有該項配置,肯呢個devtools不會起作用,即應用不會restart   這個要手動加進去

-->
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
   </build>

第二部 啟動專案即可

1. devtools會監聽classpath下的檔案變動,並且會立即重啟應用(發生在儲存時機),注意:因為其採用的虛擬機器機制,該項重啟是很快的。
2. devtools可以實現頁面熱部署(即頁面修改後會立即生效,這個可以直接在application.properties檔案中配置spring.thymeleaf.cache=false來實現(這裡注意不同的模板配置不一樣)

如果使用idea,必須確保開啟執行時編譯才行

1,設定File ->Setting ->Compile: 勾選“Make project automatically”選項

使用快捷鍵ctrl+alt+shift+/,選擇選項Registry,開啟下面的介面 並找到圖中紅框的選項"compller.automake.allow.when.app.running"並勾選

3、重啟idea即可

 

idea新建一個spring-boot工程,勾選DevTools即可,pom就會引入相應jar ,該jar預設是runtime 也就是隻在執行時使用,打包時不打進去
    

 

devtools 原理說明

Spring Boot 包括一組額外的工具,可以使應用程式開發體驗更加愉快。 spring-boot-devtools 模組可以包含在任何專案中,它可以節省大量的時間。 想要使用devtools支援,只需將模組依賴關係新增到你的構建中:

Maven:

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

Gradle:

dependencies {
    compile("org.springframework.boot:spring-boot-devtools")
}

執行打包的應用程式時,開發人員工具會自動禁用。如果你通過 Java -jar 或者其他特殊的類載入器進行啟動時,都會被認為是“生產環境的應用”。

將依賴標記為 optional 可選是一種最佳做法,可以防止將devtools依賴傳遞到其他模組中。Gradle 不支援開箱即用的optional依賴項,你可以參考propdeps-plugin。

屬性預設設定

Spring Boot 支援的一些庫中會使用快取來提高效能。例如模版引擎將快取編譯後的模板,以避免重複解析模板檔案。 此外,Spring MVC可以在服務靜態資源時向響應中新增HTTP快取頭。

雖然快取在生產中非常有益,但它在開發過程中可能會產生反效果,它會阻止你看到剛剛在應用程式中進行的更改。 因此,spring-boot-devtools 將預設禁用這些快取選項。

快取選項通常在application.properties 檔案中配置。例如,Thymeleaf提供了spring.thymeleaf.cache屬性。spring-boot-devtools 模組不需要手動設定這些屬性,而是自動應用合理的開發時配置。

自動重啟

spring-boot-devtools會在類路徑上的檔案發生更改時自動重啟。 這在IDE中工作時可能是一個有用的功能,因為它為程式碼更改提供了非常快的反饋迴圈。 預設情況下會監視類路徑上的所有變動,但請注意,某些資源(如靜態資源和檢視模板)不需要重啟應用程式。

觸發重啟

當DevTools監視類路徑資源時,觸發重啟的唯一方法是更新類路徑。 導致類路徑更新的方式取決於你正在使用的IDE。在Eclipse中,儲存修改的檔案將導致類路徑被更新並觸發重啟。 在IntelliJ IDEA中,構建專案( Build -> Make Project )將具有相同的效果。

重新啟動和重新載入

Spring Boot提供的重新啟動技術使用了兩個類載入器。 不改變的類(例如,來自第三方jar的)被載入到 base 類載入器中。 你正在開發的類被載入到 restart 類載入器中。 當應用程式重啟時, restart載入器將被丟棄,並建立一個新的類載入器。 這種方法意味著應用程式重啟通常比“冷啟動”快得多,因為 base 載入器已經已載入並且可用。

1. 排除資源

某些資源在更改時不一定需要觸發重啟。 例如,可以直接編輯Thymeleaf模板。 預設情況下,更改/META-INF/maven , /META-INF/resources , /resources , /static , /public或/templates中的資源不會觸發重啟,但會觸發實時重新載入。 如果要自定義這些排除項,可以使用spring.devtools.restart.exclude屬性。 例如,要僅排除/static和/public你將設定以下內容:

spring.devtools.restart.exclude = static / **,public / ** 

如果你想保留上面的預設(情況下的)值並新增其他的排除項,你可以使用

spring.devtools.restart.additional-exclude 屬性。

2. 監控額外的路徑

當你對不在類路徑中的檔案進行更改時,可能需要重啟或重新載入應用程式。為此,請使用spring.devtools.restart.additional-paths 屬性來配置監視其他路徑的更改。你可以使用上述的 spring.devtools.restart.exclude 屬性來控制附加路徑下的更改是否會觸發完全重啟或只是實時重新載入 。

3. 禁用重啟

如果不想使用重啟功能,可以使用spring.devtools.restart.enabled屬性來禁用它。 在大多數情況下,你可以在application.properties中設定此項(這仍將初始化重啟類載入器,但不會監視檔案更改)。

例如,如果你需要完全禁用重啟支援,因為它不適用於特定庫,則需要在呼叫SpringApplication.run(…)之前設定System屬性。 例如:

public static void main(String[] args) {
    System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(MyApp.class, args);
} 

4. 使用觸發檔案

如果你使用自動編譯已更改檔案的IDE,則可能希望僅在特定時間觸發重啟。 為此,你可以使用“觸發檔案”,這是一個特殊檔案,當你要實際觸發重啟檢查時,必須修改它。 更改檔案只會觸發檢查,只有在Devtools檢測到它必須執行某些操作時才會重啟。 觸發檔案可以手動更新,也可以通過IDE外掛更新。

要使用觸發器檔案,請使用spring.devtools.restart.trigger-file屬性。

如果你希望將spring.devtools.restart.trigger-file設定為全域性配置,可以參考下面第四小節。

5. 自定義重啟類載入器

如上面重新啟動和重新載入部分所述,重啟功能是通過使用兩個類載入器實現的。 對於大多數應用程式,此方法執行良好,但有時可能會導致類載入問題。

預設情況下,IDE中的任何開啟的專案都會使用“restart”類載入器載入,任何常規.jar檔案將使用“base”類載入器載入。 如果你在多模組專案上工作,但不是每個模組都匯入到IDE中,則可能需要自定義配置。 為此,你可以建立一個META-INF/spring-devtools.properties檔案。

spring-devtools.properties檔案可以包含restart.exclude. 和restart.include. 字首的屬性。 include元素是應該被放入“restart”類載入器的專案, exclude元素是應該放入“base”類載入器的專案。 屬性的值是應用於類路徑下的正則表示式。

例如:

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar

針對通用Mapper,可以做如下配置:

restart.include.mapper=/mapper-[\\w-\\.]+jar

所有屬性的鍵值(名字,companycommonlibs 部分)必須是唯一的,只有 restart.exclude. 和 restart.include. 開頭的屬性有效。

所有類路徑下面的 META-INF/spring-devtools.properties 配置檔案都會生效,所以你可以把該配置打包到每個模組中。

注:新版本的Mapper(3.4.1+)會預設增加該配置。

6. 已知限制

重啟功能對使用標準ObjectInputStream物件序列化的物件不是很好 。如果需要反序列化資料,可能需要使用Spring的ConfigurableObjectInputStream配合Thread.currentThread().getContextClassLoader() 使用。

不幸的是,一些第三方庫都不考慮在使用上下文類載入器的情況下反序列化。 如果你發現這樣的問題,你需要向原作者請求修復。

實時載入

spring-boot-devtools模組包含嵌入式LiveReload伺服器,可以在資源更改時用於觸發瀏覽器重新整理。 LiveReload瀏覽器擴充套件程式支援Chrome,Firefox和Safari,你可以從livereload.com免費下載。

如果你不想在應用程式執行時啟動LiveReload伺服器,則可以將spring.devtools.livereload.enabled屬性設定為false 。

同一時間只能執行一個LiveReload伺服器。 開始應用程式之前,請確保沒有其他LiveReload伺服器正在執行。如果從IDE啟動多個應用程式,則只有第一個應用程式將支援LiveReload。

全域性設定

你可以通過向$HOME資料夾新增名為.spring-boot-devtools.properties的檔案來配置全域性devtools設定(請注意,檔名以“.”開頭)。 新增到此檔案的任何屬性將適用於你的計算機上使用devtools的所有 Spring Boot應用程式。 例如,要配置重啟始終使用觸發器檔案 ,你可以新增以下內容:

〜/ .spring-boot-devtools.properties
  •  
spring.devtools.reload.trigger-file=.reloadtrigger