Spring Boot包括一組額外的工具,這些工具可使應用程序開發體驗變得更加愉快,spring-boot-devtools
模塊能夠包含在任何項目中,以提供額外的development-time特性,要包含devtools支持,請將模塊依賴項添加到你的構建中,以下所示的Maven和Gradle列表:html
Maven.java
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
Gradle.git
dependencies { compile("org.springframework.boot:spring-boot-devtools") }
在運行徹底打包的應用程序時,開發工具會自動被禁用,若是你的應用程序是從java -jar
啓動的,或者是從一個特殊的類加載器開始的,那麼它就被認爲是一個「生產應用程序」。將依賴項標記爲Maven中的可選項或使用compileOnly
在Gradle中是一種最佳實踐,它能夠防止devtools被傳遞到其餘使用你的項目的模塊中。
默認狀況下,從新打包的存檔不包含devtools,若是你想要使用某些
遠程devtools特性,你須要禁用該
excludeDevtools
構建屬性來包含它,該屬性同時支持Maven和Gradle插件。
Spring Boot所支持的幾個庫都使用緩存來提升性能。例如,模板引擎緩存已編譯的模板以免重複解析模板文件。另外,Spring MVC能夠在提供靜態資源時向響應添加HTTP緩存標頭。github
雖然緩存在生產中很是有益,但在開發過程當中可能會產生相反的效果,使你沒法看到你在應用程序中所作的更改。出於這個緣由,spring-boot-devtools
在默認狀況下禁用了緩存選項。web
緩存選項一般由application.properties
文件中的設置配置,例如,Thymeleaf提供了spring.thymeleaf.cache
屬性,spring-boot-devtools
模塊不須要手動設置這些屬性,而是自動應用合理的development-time配置。spring
有關devtools應用的屬性的完整列表,請參見 DevToolsPropertyDefaultsPostProcessor。
當類路徑上的文件發生更改時,使用spring-boot-devtools
的應用程序將自動從新啓動,當在IDE中工做時,這多是一個有用的特性,由於它爲代碼更改提供了很是快速的反饋循環。默認狀況下,類路徑中指向文件夾的任何條目都會被監控是否有更改,請注意,某些資源(如靜態資產和視圖模板)不須要從新啓動應用程序。segmentfault
引起重啓
當DevTools監視類路徑資源時,觸發重啓的唯一方法是更新類路徑,致使類路徑更新的方式取決於你使用的IDE。在Eclipse中,保存修改後的文件會致使類路徑被更新並觸發從新啓動,在IntelliJ IDEA中,構建項目(
Build -> Build Project
)具備相同的效果。瀏覽器
只要啓用了forking,你就可使用支持的構建插件(Maven和Gradle)來啓動應用程序,由於DevTools須要一個獨立的應用程序類加載器才能正常運行。默認狀況下,Gradle和Maven在類路徑上檢測DevTools時是這樣作的。
當與LiveReload一塊兒使用時,自動重啓很是有效。詳情 請參閱LiveReload部分。若是你使用JRebel,自動從新啓動將被禁用,以支持動態類重載。其餘devtools特性(如LiveReload和property overrides)仍然可使用。
在從新啓動時,DevTools依賴於應用程序上下文的shutdown hook關閉它,若是你已經禁用了shutdown hook(
SpringApplication.setRegisterShutdownHook(false)
),那麼它將沒法正常工做。
當決定是否在類路徑上的條目發生更改時觸發重啓時,DevTools自動忽略了名爲spring-boot
、spring-boot-DevTools
、spring-boot-autoconfigure
、spring-boot-actuator
和spring-boot-starter
的項目。
DevTools須要定製被ApplicationContext
使用的ResourceLoader
,若是你的應用程序已經提供了一個,它將被包裝,不支持在ApplicationContext
上直接覆蓋getResource
方法。
重啓和從新加載
Spring Boot提供的重啓技術使用兩個類加載器。不改變的類(例如,來自第三方jar的類)被加載到一個基類加載器中,正在積極開發的類被加載到重啓類加載器中,當應用程序從新啓動時,重啓類加載器將被丟棄,並建立一個新的類加載器。這種方法意味着應用程序從新啓動一般要比「冷啓動」快得多,由於基類加載器已經可用並填充了。spring-mvc
若是發現從新啓動對應用程序來講不夠快,或者遇到了類加載問題,你能夠考慮從新加載技術,如零週轉期的JRebel,這些工做經過在加載類時重寫類,使它們更易於從新加載。緩存
默認狀況下,每次應用程序從新啓動時,都會記錄顯示狀態評估增量的報告。報告顯示了在進行更改(如添加或刪除bean和設置配置屬性)時對應用程序的自動配置的更改。
若要禁用報告的日誌記錄,請設置如下屬性:
spring.devtools.restart.log-condition-evaluation-delta=false
某些資源在更改時不必定須要觸發從新啓動,例如,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
屬性代替。
當你對不在類路徑上的文件進行更改時,你可能但願你的應用程序從新啓動或從新加載。能夠這樣作,使用spring.devtools.restart.additional-paths
屬性來配置額外的路徑以監視更改,你可使用前面描述的spring.devtools.restart.exclude
屬性來控制在附加路徑下的更改是否會觸發徹底重啓或從新加載。
若是你不想使用重啓功能,你可使用spring.devtools.restart.enabled
屬性禁用它。在大多數狀況下,你能夠在application.properties中
設置此屬性。(這樣作仍然初始化重啓類加載器,但它不注意文件的更改)。
若是你須要徹底禁用從新啓動支持(例如,由於它不能與特定的庫一塊兒工做),那麼你須要設置spring.devtools.restart.enabled
System
屬性爲false
,而後調用SpringApplication.run(…)
,以下例所示:
public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); }
若是你使用一個持續編譯已更改文件的IDE,你可能只須要在特定的時間觸發從新啓動,爲此,你可使用一個「觸發文件」,它是一個特殊的文件,當你想要實際觸發從新啓動檢查時,必須對其進行修改。更改文件只會觸發檢查,只有當Devtools檢測到它必須作某事時纔會從新啓動。觸發器文件能夠手動更新,也可使用IDE插件進行更新。
要使用一個觸發器文件,請將spring.devtools.restart.trigger-file
屬性設置爲觸發器文件的路徑。
你可能想要設置
spring.devtools.restart.trigger-file
做爲
全局設置,以便全部的項目都以相同的方式運行。
如前所述,在重啓與重載部分中,從新啓動功能是經過使用兩個類加載器實現的,對於大多數應用程序來講,這種方法運行良好。然而,它有時會致使類加載問題。
默認狀況下,IDE中的任何開放項目都包含「重啓」類加載器,任何常規的.jar
文件都裝載了「基礎」類加載器,若是你在一個多模塊項目中工做,而不是每一個模塊都導入到你的IDE中,你可能須要定製一些東西。爲此,你能夠建立一個META-INF/spring-devtools.properties
文件。
spring-devtools.properties
能夠包含有restart.exclude
和restart.include
的屬性,include
元素是應該被拉到「重啓」類加載器中的項,而exclude
元素則是應該被推入「基礎」類加載器的項,屬性的值是應用於類路徑的regex模式,以下例所示:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
全部屬性鍵必須是惟一的,只有屬性以restart.include.
或restart.exclude.
開頭才被承認。
全部類路徑下的
META-INF/spring-devtools.properties
被加載,你能夠在項目中或項目使用的庫中打包文件。
經過使用標準ObjectInputStream
來反序列化的對象,從新啓動功能不會很好地工做,若是須要反序列化數據,可能須要使用Spring的ConfigurableObjectInputStream
和Thread.currentThread().getcontextclassloader()
。
不幸的是,一些第三方庫在不考慮上下文類加載器的狀況下反序列化。若是你發現這樣的問題,你須要向原始做者請求修復。
spring-boot-devtools
模塊包含一個嵌入式的LiveReload服務器,當資源被更改時,它能夠用來觸發瀏覽器刷新。LiveReload瀏覽器擴展能夠從livereload.com免費提供給Chrome、Firefox和Safari。
若是你不想在應用程序運行時啓動LiveReload服務器,則能夠設置spring.devtools.livereload.enabled
屬性爲false
。
你一次只能運行一個LiveReload服務器,在啓動應用程序以前,確保沒有其餘的LiveReload服務器在運行。若是你在IDE中啓動多個應用程序,那麼只有第一個應用程序獲得了LiveReload的支持。
你能夠經過添加名爲.spring-boot-devtools.properties
的文件來配置全局devtools設置到$HOME
文件夾(注意文件名以「.」開頭)。添加到該文件的任何屬性都適用於使用devtools的機器上的全部Spring Boot應用程序。例如,要配置從新啓動以始終使用觸發器文件,你須要添加如下屬性:
~/.spring-boot-devtools.properties.
spring.devtools.reload.trigger-file=.reloadtrigger
Spring Boot開發工具並不侷限於本地開發,在遠程運行應用程序時,還可使用幾個特性。遠程支持是可選的,要啓用它,你須要確保將devtools
包含在從新打包的歸檔文件中,以下面的清單所示:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludeDevtools>false</excludeDevtools> </configuration> </plugin> </plugins> </build>
而後你須要設置spring.devtools.remote.secret
屬性,以下面的示例所示:
spring.devtools.remote.secret=mysecret
在遠程應用程序上啓用
spring-boot-devtools
是一種安全風險,你不該該在生產部署上啓用支持。
遠程devtools支持分兩部分提供:一個服務器端端點接受鏈接,一個客戶端應用程序在IDE中運行。當spring.devtools.remote.secret
屬性被設置時,服務器組件自動啓用,客戶端組件必須手動啓動。
遠程客戶端應用程序設計爲從你的IDE中運行,你須要運行org.springframework.boot.devtools.RemoteSpringApplication
與你鏈接到的遠程項目相同的類路徑,應用程序的惟一必需參數是它鏈接的遠程URL。
例如,若是你正在使用Eclipse或STS,而且你有一個名爲my-app
的項目,你已經部署到Cloud Foundry,那麼你將執行如下操做:
Run
菜單選擇Run Configurations…
。Java Application
「launch configuration」。my-app
項目。org.springframework.boot.devtools.RemoteSpringApplication
做爲主類。https://myapp.cfapps.io
到Program arguments
(或任何遠程URL)。正在運行的遠程客戶端可能相似於如下清單:
. ____ _ /\\ / ___'_ __ _ _(_)_ __ __ _ ( ( )\___ | '_ | '_| | '_ \/ _` | \\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' __ _ _ ___ _ \ \ \ \ | _ \___ _ __ ___| |_ ___ \ \ \ \ \/ _ \ _/ -_) ) ) ) ) ' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / / =========|_|==============|___/===================================/_/_/_/ :: Spring Boot Remote :: 2.0.5.RELEASE 2015-06-10 18:25:06.632 INFO 14938 --- [main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/ spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/ spring-boot-samples/spring-boot-sample-devtools) 2015-06-10 18:25:06.671 INFO 14938 --- [main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy 2015-06-10 18:25:07.043 WARN 14938 --- [main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'. 2015-06-10 18:25:07.074 INFO 14938 --- [main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2015-06-10 18:25:07.130 INFO 14938 --- [main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
由於遠程客戶端使用與實際應用程序相同的類路徑,它能夠直接讀取應用程序屬性。這是
spring.devtools.remote.secret
屬性被讀取並傳遞給服務器進行身份驗證的方法。
使用
https://
做爲鏈接協議老是明智的,這樣就能夠加密傳輸並不能截獲密碼。
若是須要使用代理訪問遠程應用程序,請配置spring.devtools.remote.proxy.host
和spring.devtools.remote.proxy.port
屬性。
遠程客戶端監控你的應用程序類路徑,以與本地重啓相同的方式進行更改。任何更新的資源都被推送到遠程應用程序,而且(若是須要的話)觸發重啓。若是你在一個使用不是本地的雲服務的特性上進行迭代,這將是頗有幫助的。通常來講,遠程更新和從新啓動比完整的重建和部署週期要快得多。
文件只在遠程客戶機運行時受到監視,若是在啓動遠程客戶端以前更改一個文件,則不會將其推送到遠程服務器。
可執行jar能夠用於生產部署,因爲它們是自包含的,因此它們也很是適合基於雲的部署。
對於額外的「生產就緒」特性,如健康、審計和指標REST或JMX端點,考慮添加spring-boot-actuator
,參見第V部分,「Spring Boot Actuator:生產就緒特性」的詳細信息。
如今你應該瞭解瞭如何使用Spring Boot和你應該遵循的一些最佳實踐,如今,你能夠深刻了解特定的Spring Boot特性,或者你能夠跳過,閱讀Spring Boot的「生產就緒」方面的內容。