一、开发人员工具
Spring Boot包括一组附加的工具,可以使应用程序开发体验更愉快一些。Spring Boot devtools模块可以包含在任何项目中,以提供额外的开发时特性。要包含devtools支持,请将模块依赖项添加到构建中,如以下Maven所示:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
当应用程序运行工具被完全禁用时,将自动打包。如果你的应用程序是从java-jar启动的,或者是从一个特殊的类加载器启动的,那么它就被认为是一个“生产应用程序”。如果这不适用于你(即,如果你从容器运行应用程序),请考虑排除devtools或设置-Dspring.devtools.restart.enabled=false的系统属性。
在Maven中将依赖项标记为可选的,可以防止devtools被传递地应用到使用你的项目的其他模块。
默认情况下,重新打包的存档不包含devtools。如果要使用某个远程devtools功能,则需要禁用excludeDevtools
build属性以包含它。Maven插件都支持该属性。
1、属性默认值
Spring Boot支持的一些库使用缓存来提高性能。例如,模板引擎缓存已编译的模板,以避免重复解析模板文件。另外,Spring MVC可以在服务静态资源时向响应添加HTTP缓存头。
虽然缓存在生产中有一定好处,但在开发过程中它可能会适得其反,使你无法看到刚刚在应用程序中所做的更改。因此, spring-boot-devtools默认情况下禁用了缓存选项。
缓存选项通常由application.properties。例如,Thymeleaf提供spring.thymeleaf.cache缓存。spring-boot-devtools模块不需要手动设置这些属性,而是自动应用合理的开发时配置。
因为在开发Spring MVC和Spring WebFlux 应用程序时需要更多关于web请求的信息,开发工具将为web日志记录组启用调试日志记录。这将为你提供有关传入请求、哪个处理程序正在处理它、响应结果等的信息。如果你希望记录所有请求详细信息(包括潜在的敏感信息),可以打开spring.http.log-request-details配置属性。
如果不希望应用属性默认值,可以设置spring.devtools.add-properties设置为false
应用程序属性.
二、自动重启
当classpath 上的文件发生变化时,使用spring-boot-devtools的应用程序会自动重新启动。在IDE中工作时,这可能是一个有用的特性,因为它为代码更改提供了一个非常快速的反馈循环。默认情况下,classpath 上指向文件夹的任何条目都会被监视以进行更改。请注意,某些资源(如静态资产和视图模板)不需要重新启动应用程序。
1、触发重新启动
由于DevTools监视classpath 资源,触发重新启动的唯一方法是更新classpath 。更新类路径的方式取决于所使用的IDE。在Eclipse中,保存修改过的文件会导致类路径被更新并触发重新启动。在IntelliJ中,构建项目(Build+→+Build project)具有相同的效果。
只要启用了forking,就可以使用支持的构建插件(Maven和Gradle)启动应用程序,因为DevTools需要一个独立的应用程序类加载器才能正常运行。默认情况下,应用程序fork和Maven进程。
DevTools依赖于应用程序上下文的shutdown在重启期间关闭它。如果你禁用了关闭,它将无法正常工作(SpringApplication.setRegisterShutdownHook(false))。
当决定classpath 上是否应该在发生更改时触发重新启动时,DevTools会自动忽略名为spring boot、spring boot DevTools、spring boot autoconfigure、spring boot actuator和spring boot starter的项目。
DevTools需要自定义ApplicationContext使用的ResourceLoader
。如果你的应用程序已经提供了一个,它将被封装。不支持直接重写ApplicationContext
上的getResource
方法。
Spring Boot提供的重启技术通过使用两个类加载器来工作。不变的类(例如,来自第三方jar的类)被加载到基类加载器中。你正在开发的类被加载到重新启动类加载器中。当应用程序重新启动时,重新启动的类加载器将被丢弃,并创建一个新的类加载器。这种方法意味着应用程序重启通常比“冷启动”快得多,因为基本类加载器已经可用并已填充。
如果发现应用程序的重启速度不够快,或者遇到类加载问题,可以考虑从ZeroTurnaround重新加载JRebel等技术。它们的工作方式是在类加载时重写类,使它们更易于重新加载。
2、日志记录
默认情况下,每次应用程序重新启动时,都会日志记录增量的内容。当你进行诸如添加或删除bean以及设置配置属性之类的更改时,该报告将显示对应用程序自动配置的更改。
要禁用报告的日志记录,请设置以下属性:
spring.devtools.restart.log-condition-evaluation-delta=false
3、排除资源
某些资源不一定需要在更改时触发重新启动。例如,可以就地编辑ELEAF模板。默认情况下,更改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。请改为排除其他属性。
4、监视其它路径
当你对不在classpath上的文件进行更改时,你可能希望重新启动或重新加载应用程序。为此,请使用spring.devtools.restart.additional-paths属性配置其他路径以监视更改。你可以用spring.devtools.restart.exclude属性,用于控制其它路径下的更改是触发完全重新启动还是实时重新加载。
5、禁用重新启动
如果不想使用重新启动功能,可以使用spring.devtools.restart.enabled属性。在大多数情况下,你可以在应用程序属性(这样做仍然会初始化重启类加载器,但它不会监视文件更改)。
如果需要完全禁用重新启动支持(例如,因为它不适用于特定的库),则需要设置spring.devtools.restart.enabled
System
属性在调用前设置为SpringApplication.run(…),如下例所示:
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
6、使用触发器文件
如果你使用的IDE连续编译更改的文件,你可能更希望只在特定时间触发重新启动。为此,你可以使用“trigger”文件,这是一个特殊的文件,当你想要实际触发重新启动检查时,必须对其进行修改。
对该文件的任何更新都将触发检查,但只有在Devtools检测到该文件有问题时才会真正重新启动。
要使用触发器文件,请设置spring.devtools.restart.trigger-file属性设置为触发器文件的名称(不包括任何路径)。触发器文件必须出现在类路径的某个地方。
例如,如果你有一个以下结构的项目:
src
+- main
+- resources
+- .reloadtrigger
那么你的触发器文件属性将是:
spring.devtools.restart.trigger-file=.reloadtrigger
现在只有在src/main/resources/.reloadtrigger更新时才会重新启动。
可能需要设置spring.devtools.restart.trigger-file作为全局设置,以便所有项目的行为方式相同。
有些ide的特性使你无需手动更新触发器文件。spring tools for eclipse和intellij idea(终极版)都有这样的支持。使用Spring工具,你可以使用控制台视图中的“reload”按钮(只要你的触发器文件名为.reloadtrigger)。对于IntelliJ IDEA,你可以按照其文档中的说明进行操作。
7、自定义重新启动类加载器
通过使用两个类加载器实现重启功能。对于大多数应用程序,这种方法效果很好。但是,它有时会导致类加载问题。
在任何一个项目中,默认情况下,用任何一个“classbase”加载的classloader都是打开的。如果你处理的是多模块项目,并且不是每个模块都导入到IDE中,那么你可能需要定制一些东西。为此,你可以创建一个META-INF/spring-devtools.properties文件。
spring-devtools.properties文件可以包含前缀为的属性restart.exclude以及restart.include元素是应该向上拉入“restart”类加载器的项,exclude
元素是应该向下推入“base”类加载器的项。该属性的值是应用于类路径的正则表达式模式,如下例所示:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\\.jar
所有属性键必须唯一。只要属性值以restart.include.
. 或者restart.exclude.这是值得考虑的。
所有META-INF/spring-devtools.properties从类路径加载。可以将文件打包到项目中,也可以打包到项目使用的库中。
8、已知限制
对于使用标准ObjectInputStream反序列化的对象,重新启动功能不能很好地工作。如果需要反序列化数据,则可能需要将Spring的ConfigurableObjectInputStream
与Thread.currentThread().getContextClassLoader()。
不幸的是,一些第三方库反序列化时没有考虑上下文类加载器。
三、LiveReload
spring-boot-devtools模块包括一个嵌入式LiveReload服务器,当资源发生更改时,该服务器可用于触发浏览器刷新。LiveReload浏览器扩展可免费用于Chrome、Firefox和Safarilivereload.com网站。
如果不想在应用程序运行时启动LiveReload服务器,可以设置spring.devtools.livereload.enabled属性为false。
一台服务器一次只能运行一次。在启动应用程序之前,请确保没有其他LiveReload服务器正在运行。如果从IDE启动多个应用程序,则只有第一个应用程序支持LiveReload。
要在文件更改时触发LiveReload,必须启用自动重新启动。
四、全局设置
你可以通过将以下任何文件添加到$HOME/.config/spring-boot目录来配置全局devtools设置:
spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml
添加到这些文件中的任何属性都适用于计算机上使用devtools的所有Spring引导应用程序。例如,要将restart配置为始终使用触发器文件,可以将以下属性添加到spring-boot-devtools文件中:
spring.devtools.restart.trigger-file=.reloadtrigger
如果在$HOME/.config/spring-boot中找不到devtools配置文件,则会在$HOME目录的根目录中搜索是否存在.spring-boot-devtools.propertie文件。这允许你与不支持$HOME/.config/spring-boot位置的旧版本Spring Boot上的应用程序共享devtools全局配置。
devtools属性/yaml文件中不支持配置文件。在.spring-boot-devtools.properties不会影响配置文件特定配置文件的加载。特定于概要文件的文件名(形式为sspring-boot-devtools-<profile>.properties)和spring.config.activate.on-profile不支持YAML和属性文件中的配置文件文档。
FileSystemWatcher的工作方式是以一定的时间间隔轮询类更改,然后等待预定义的静默期以确保不再有更改。由于Spring-Boot完全依赖IDE来编译文件并将其复制到Spring-Boot可以读取文件的位置,因此你可能会发现,在devtools重新启动应用程序时,有时某些更改不会反映出来。如果你经常观察到这样的问题,试着增加spring.devtools.restart.poll-interval和spring.devtools.restart.quiet-period参数设置为适合你的开发环境的值:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
监视的类路径目录现在每2秒轮询一次,并保持1秒的静默期,以确保没有其他类更改。
五、远程应用程序
Spring Boot开发工具并不局限于本地开发。在远程运行应用程序时,还可以使用多种功能。远程支持是可选的,因为启用它可能会带来安全风险。只有在受信任的网络上运行或使用SSL进行保护时,才应启用它。如果这两个选项都不可用,则不应使用DevTools的远程支持。决不应在生产部署上启用支持。
要启用它,你需要确保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。与任何重要的密码或秘密一样,该值应该是唯一,这样就不会被猜测或强制使用。
远程devtools支持分为两部分:接受连接的服务器端端点和在IDE中运行的客户端应用程序。服务器组件在spring.devtools.remote.secret文件已设置机密属性。客户端组件必须手动启动。
运行远程客户端应用程序
远程客户端应用程序设计为从IDE中运行。你得跑了org.springframework.boot.devtools.RemoteSpringApplication与你连接到的远程项目具有相同的类路径。应用程序的唯一必需参数是它所连接的远程URL。
例如,如果您使用的是Eclipse或STS,并且您有一个名为my app的项目已部署到Cloud Foundry,则可以执行以下操作:
从“运行”Run Configurations…“运行配置…”。
创建一个新的Java Application “launch configuration”。
浏览
my-app
项目。使用org.springframework.boot.devtools.RemoteSpringApplication作为主类。
添加https://myapp.cfapps.io至Program arguments(或者不管您的远程URL是什么)。
正在运行的远程客户端可能类似于以下列表:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.4.2-SNAPSHOT
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-project/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code)
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连接是加密的,所以不建议总是使用https连接密码。如果需要使用代理访问远程应用程序,请配置spring.devtools.remote.proxy.host以及spring.devtools.remote.proxy.port属性。
远程更新
远程客户端以与本地重启相同的方式监视应用程序类路径的更改。任何更新的资源都会推送到远程应用程序,并(如果需要)触发重新启动。如果你迭代使用本地没有的云服务的功能,这会很有帮助。通常,远程更新和重新启动要比完整的重建和部署周期快得多。
在较慢的开发环境中,可能会出现静置时间不够的情况,并且类中的更改可能会被拆分为批处理。上载第一批类更改后,服务器将重新启动。无法将下一批发送到应用程序,因为服务器正在重新启动。
这通常表现为RemoteSpringApplication
日志中关于未能上载某些类的警告,以及随后的重试。但这也可能导致应用程序代码不一致,以及在上载第一批更改后无法重新启动。如果你经常观察到这样的问题,试着增加spring.devtools.restart.poll-interval和spring.devtools.restart.quiet-period参数设置为适合你的开发环境的值。
有在远程客户端运行时才监视文件。如果在启动远程客户端之前更改文件,则不会将其推送到远程服务器。
喜欢朋友帮忙关注和转发Spring中文社区(加微信群,关注后加我微信入群):
Spring 核心技术、MVC、数据访问和集成技术可以在公众号内查看你需要的内容。
本文分享自微信公众号 - Spring中文社区(gh_81d233bb13a4)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4672998/blog/4883661