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的“生产就绪”方面的内容。