20. 开发者工具
Spring Boot包括一组额外的工具,这些工具可以使应用程序开发体验变得更加愉快,spring-boot-devtools
模块可以包含在任何项目中,以提供额外的development-time特性,要包含devtools支持,请将模块依赖项添加到你的构建中,如下所示的Maven和Gradle列表:
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
启动的,或者是从一个特殊的类加载器开始的,那么它就被认为是一个“生产应用程序”。将依赖项标记为Maven中的可选项或使用compileOnly
在Gradle中是一种最佳实践,它可以防止devtools被传递到其他使用你的项目的模块中。
默认情况下,重新打包的存档不包含devtools,如果你想要使用某些远程devtools特性,你需要禁用该excludeDevtools
构建属性来包含它,该属性同时支持Maven和Gradle插件。
20.1 属性默认值
Spring Boot所支持的几个库都使用缓存来提高性能。例如,模板引擎缓存已编译的模板以避免重复解析模板文件。另外,Spring MVC可以在提供静态资源时向响应添加HTTP缓存标头。
虽然缓存在生产中非常有益,但在开发过程中可能会产生相反的效果,使你无法看到你在应用程序中所做的更改。出于这个原因,spring-boot-devtools
在默认情况下禁用了缓存选项。
缓存选项通常由application.properties
文件中的设置配置,例如,Thymeleaf提供了spring.thymeleaf.cache
属性,spring-boot-devtools
模块不需要手动设置这些属性,而是自动应用合理的development-time配置。
有关devtools应用的属性的完整列表,请参见DevToolsPropertyDefaultsPostProcessor。
20.2 自动重启
当类路径上的文件发生更改时,使用spring-boot-devtools
的应用程序将自动重新启动,当在IDE中工作时,这可能是一个有用的特性,因为它为代码更改提供了非常快速的反馈循环。默认情况下,类路径中指向文件夹的任何条目都会被监控是否有更改,请注意,某些资源(如静态资产和视图模板)不需要重新启动应用程序。
引发重启
当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的类)被加载到一个基类加载器中,正在积极开发的类被加载到重启类加载器中,当应用程序重新启动时,重启类加载器将被丢弃,并创建一个新的类加载器。这种方法意味着应用程序重新启动通常要比“冷启动”快得多,因为基类加载器已经可用并填充了。
如果发现重新启动对应用程序来说不够快,或者遇到了类加载问题,你可以考虑重新加载技术,如零周转期的JRebel,这些工作通过在加载类时重写类,使它们更易于重新加载。
20.2.1 日志记录条件评估中的改变
默认情况下,每次应用程序重新启动时,都会记录显示状态评估增量的报告。报告显示了在进行更改(如添加或删除bean和设置配置属性)时对应用程序的自动配置的更改。
若要禁用报告的日志记录,请设置以下属性:
spring.devtools.restart.log-condition-evaluation-delta=false
20.2.2 排除资源
某些资源在更改时不一定需要触发重新启动,例如,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
属性代替。
20.2.3 监视附加路径
当你对不在类路径上的文件进行更改时,你可能希望你的应用程序重新启动或重新加载。可以这样做,使用spring.devtools.restart.additional-paths
属性来配置额外的路径以监视更改,你可以使用前面描述的spring.devtools.restart.exclude
属性来控制在附加路径下的更改是否会触发完全重启或重新加载。
20.2.4 禁用重启
如果你不想使用重启功能,你可以使用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);
}
20.2.5 使用触发器文件
如果你使用一个持续编译已更改文件的IDE,你可能只需要在特定的时间触发重新启动,为此,你可以使用一个“触发文件”,它是一个特殊的文件,当你想要实际触发重新启动检查时,必须对其进行修改。更改文件只会触发检查,只有当Devtools检测到它必须做某事时才会重新启动。触发器文件可以手动更新,也可以使用IDE插件进行更新。
要使用一个触发器文件,请将spring.devtools.restart.trigger-file
属性设置为触发器文件的路径。
你可能想要设置spring.devtools.restart.trigger-file
作为全局设置,以便所有的项目都以相同的方式运行。
20.2.6 自定义重启类加载器
如前所述,在重启与重载部分中,重新启动功能是通过使用两个类加载器实现的,对于大多数应用程序来说,这种方法运行良好。然而,它有时会导致类加载问题。
默认情况下,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
被加载,你可以在项目中或项目使用的库中打包文件。
20.2.7 已知的限制
通过使用标准ObjectInputStream
来反序列化的对象,重新启动功能不会很好地工作,如果需要反序列化数据,可能需要使用Spring的ConfigurableObjectInputStream
和Thread.currentThread().getcontextclassloader()
。
不幸的是,一些第三方库在不考虑上下文类加载器的情况下反序列化。如果你发现这样的问题,你需要向原始作者请求修复。
20.3 LiveReload
spring-boot-devtools
模块包含一个嵌入式的LiveReload服务器,当资源被更改时,它可以用来触发浏览器刷新。LiveReload浏览器扩展可以从livereload.com免费提供给Chrome、Firefox和Safari。
如果你不想在应用程序运行时启动LiveReload服务器,则可以设置spring.devtools.livereload.enabled
属性为false
。
你一次只能运行一个LiveReload服务器,在启动应用程序之前,确保没有其他的LiveReload服务器在运行。如果你在IDE中启动多个应用程序,那么只有第一个应用程序得到了LiveReload的支持。
20.4 全局设置
你可以通过添加名为.spring-boot-devtools.properties
的文件来配置全局devtools设置到$HOME
文件夹(注意文件名以“.”开头)。添加到该文件的任何属性都适用于使用devtools的机器上的所有Spring Boot应用程序。例如,要配置重新启动以始终使用触发器文件,你需要添加以下属性:
~/.spring-boot-devtools.properties.
spring.devtools.reload.trigger-file=.reloadtrigger
20.5.远程应用程序
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
属性被设置时,服务器组件自动启用,客户端组件必须手动启动。
20.5.1 运行远程客户端应用程序
远程客户端应用程序设计为从你的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
属性。
20.5.2 远程更新
远程客户端监控你的应用程序类路径,以与本地重启相同的方式进行更改。任何更新的资源都被推送到远程应用程序,并且(如果需要的话)触发重启。如果你在一个使用不是本地的云服务的特性上进行迭代,这将是很有帮助的。一般来说,远程更新和重新启动比完整的重建和部署周期要快得多。
文件只在远程客户机运行时受到监视,如果在启动远程客户端之前更改一个文件,则不会将其推送到远程服务器。
21.为生产打包你的应用程序
可执行jar可以用于生产部署,由于它们是自包含的,所以它们也非常适合基于云的部署。
对于额外的“生产就绪”特性,如健康、审计和指标REST或JMX端点,考虑添加spring-boot-actuator
,参见第V部分,“Spring Boot Actuator:生产就绪特性”的详细信息。
22.下一步要读什么
现在你应该了解了如何使用Spring Boot和你应该遵循的一些最佳实践,现在,你可以深入了解特定的Spring Boot特性,或者你可以跳过,阅读Spring Boot的“生产就绪”方面的内容。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。