20.2 Automatic Restart
当类路径上的文件改变时,使用spring-boot-devtools
的应用将会自动重启.当在IDE中工作时,这可能是一个有用的特性,因为它为代码更改提供了非常快的反馈.
默认情况下,指向一个文件夹的类路径上的任何条目都会被监控确定是否更改.注意,某些资源,例如静态资源和视图模板,不需要重新启动应用程序.
Triggering a restart
因为DevTools监控类路径资源,引发重启的唯一方法就是更新类路径中的文件.引起类路径更新的方式取决于您正在使用的IDE.
在Eclipse中,保存修改后的文件会导致类路径被更新并因此触发重新启动.在IntelliJ IDEA中,构建项目(Build -> Build )具有相同的效果。Projec.
Note
只要启用了forking,你也可以通过使用支持的构建插件(Maven和Gradle)开始您的应用程序,因为DevTools需要一个独立的应用程序类加载器来正常工作. 默认情况下,Gradle和Maven在类路径上检测DevTools时是这样做的.
Tip
当与LiveReload一起使用时,自动重启将会很好的工作.详情请参见LiveReload部分. 如果您使用JRebel,自动重新启动将被禁用,以支持动态类重载.其他devtools特性(如LiveReload和属性覆盖)仍然可以使用.
Note
程序重启过程中,DevTools依赖应用程序上下文的关闭钩来关闭应用. 如果您已经禁用了关闭挂钩(
SpringApplication.setRegisterShutdownHook(false)
),那么它将无法正常工作.Note
在决定类路径上的什么条目更改触发重新启动时,DevTools自动忽略项目名为
spring-boot
,spring-boot-devtools
,spring-boot-autoconfigure
,spring-boot-actuator
和spring-boot-starter
.Note
DevTools需要自定义
ApplicationContext
使用的ResourceLoader
资源加载器. 如果您的应用程序已经提供了一个,那么它将被打包.直接覆盖ApplicationContext
的getResource
方法将不受支持.
Restart vs Reload
Spring Boot提供的重启技术使用两个类加载器.不改变的类(例如,来自第三方jar的类)被加载到一个基类加载器中.
当前正在开发的类被加载到重启类加载器中. 当应用程序重新启动时,重启类加载器将被丢弃,并创建一个新的类加载器.
这种方法意味着应用程序重新启动通常比冷启动快得多,因为基类加载器已经可用并加载了.
如果您发现重新启动对应用程序不够快,或者遇到了类加载问题,那么您可以考虑重新加载技术,例如ZeroTurnaround公司的JRebel.
这些工作通过重写类,使它们更适合重载.
Logging changes in condition evalution
默认情况下,每次应用程序重新启动时,都会记录显示启动状态评估的报告.报告显示了您的应用程序的自动配置的变化,如添加或删除实例和设置配置属性等.
要禁用报告的日志记录,请设置以下属性:
spring.devtools.restart.log-codition-evaluation-delta=false
Excluding Resources
某些资源在更改时不一定需要触发重新启动.例如,Thymeleaf模板可以就地编辑.默认情况下,/META-INF/maven
、/META-INF/resources
、/resources
、/static
、/public
或者/templates
下的资源不会触发重新启动,但会触发重新加载.
如果您想配置这些排除特性,您可以使用spring.devtools.restart.exclude属性.例如,仅排除/static
和/public
,您将设置以下属性:
spring.devtools.restart.exclude=static/**,public/**
Tip
如果你想保留这些默认配置且想增加额外的排除特性,请替换使用
spring.devtools.restart.additional-exclude
属性.Watching Additional Paths
您可能希望更改不是类路径上文件时,你的应用程序也能重新启动或重新加载.要这样做,可以使用
spring.devtools.restart.additional-paths
属性配置路径,让其监控文件更改. 您可以使用之前将解过的spring.devtools.restart.exclude
属性来控制排除额外路径下的文件变化触发全面重启或重新加载.Disabling Restart
如果您不想使用重启功能,您可以配置
spring.devtools.restart.enabled
属性为false
来禁用它.在大多数情况下,您可以在你的application.properties文件中设置此属性(这么做仍然初始化启动类加载器,但它不会监控文件更改).
如果你需要完全禁用重启支持(例如,在使用特定库时它将不能很好的工作),您需要在程序调用SpringApplication.run(…)
方法前将spring.devtools.restart.enabled
系统属性设置为false,如下示例所示:
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
Using a Trigger File
如果您使用一个实时编译文件的IDE,您可能需要只在特定时间触发重新启动.为此,您可以使用触发器文件,它将是一个特殊的文件,当您想要触发重新启动检查时,该文件必须是修改过的. 更改文件只会触发检查,只有当Devtools检测到它有实际更改时才会重新启动.触发器文件可以手动更新,也可以使用IDE插件进行更新.
要想使用一个触发器文件,请将spring.devtools.restart.trigger-file
属性设置为触发器文件的路径.
Tip
您可能想要设置
spring.devtools.restart.trigger-file
作为全局设置,以便您的所有项目都以相同的方式运行.Customizing the Restart Classloader
如之前所述的Restart vs Reload章节中,重启功能是通过使用两个类加载器实现的.对于大多数应用程序来说,这种方法能很好的运行.然而,它有时会导致类加载问题.
默认情况下,您在IDE中打开任何项目都使用重启类加载器加载,并且对任何.jar
文件都使用基类加载器加载.如果您在一个多模块项目中工作并且不是每个模块都导入到您的IDE中,您可能需要定制一些东西. 为此,您可以创建一个META-INF/spring-devtools.properties
文件.
spring-devtools.properties属性文件可以包含前缀以restart.exclude和restart.include以开头的属性. include元素是应该被加入到重启类加载器中的项,而exclude元素则是应该被加入到基类加载器中的项.属性值支持被应用于类路径的正则模式,如下例所示:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
Note
所有的属性键必须是唯一的.只要属性前缀为
restart.include
或restart.exclude
开头,它才被考虑为是属性.Tip
所有类路径下的META-INF/spring-devtools.properties文件都会被加载.您可以打包到你的项目中或项目依赖的库中.
Known Limitations
当应用使用通过标准的
ObjectInputStream
反序列化后的对象时,重启功能不能很好的工作.如果你需要反序列化数据,你可能需要结合Thread.currentThread().getContextClassLoader()
方法来使用Spring’s的ConfigurableObjectInputStream
.
不幸的是,大多数第三方库反序列化时都未考虑上下文类加载器.如果你发现了类似问题,你需要向库的原作者请求Bug修复.