Spring Boot 参考指南(开发者工具)

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

上一篇:运行你的应用程序

下一篇:SpringApplication

    原文作者:博弈
    原文地址: https://segmentfault.com/a/1190000015043405
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞