??从Java1.4起,JVM引入了HotSwap,能够在Debug的时候更新类的字节码。所以使用热部署,可以实现修改代码后,无须重启服务就可以加载修改的代码,但是它只能用来更新方法体。
实例方式:
??点击当前运行的服务,再点击Edit Configurations
。
??点击要配置的程序,找到?On ‘Update’ action
?和?On frame deactivation
选择?Update classes and resources
。点击OK就可以实现热部署了。
??经过以上配置,在修改代码以后。只需要点击小锤子或者使用快捷键Command + F9
重新编译一下,就可以让改动的代码生效了。并且还会提示有多少个class被重新读取了。
?? 虽然到这里已经能实现热部署的功能了。但是Java的虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作。
Spring Boot 提供了一套额外的工具,可以让你更加愉快的开发应用。?spring-boot-devtools
?模块可以包含在任何项目中,以在开发期间提供一些有用的特性。 要使用devtools,请添加以下依赖到项目中。
Maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
?? DevTools严格意义上其实不算热部署,而是快速重启。为什么这样说呢?DevTools的实现原理是:使用两个类加载器,一个是base classloader
来加载不会被更改的类(例如,来自第三方的Jar),还有一个是restart classloader
用来加载当前正在开发的类。所以当应用程序重新启动时,restart classloader
将被丢弃,并创建一个新的类加载器。也就意味着应用程序重新启动通常比“冷启动”快得多,因为base classloader
已经填充好了并且是可用的。
??简而言之就是:通过监控类路径资源,当类路径上的文件发生更改时,自动重新启动应用程序,由于只需要重新读取被修改的类,所以要比冷启动快。
由于DevTools监控classpath资源,触发重启的唯一方法是更新classpath。 无论你使用的是IDE还是构建插件,被修改的文件都必须被重新编译以触发重启。 导致更新classpath的方式取决于你所使用的工具。
在Eclipse中,保存一个修改过的文件会导致classpath被更新并触发重启。
在IntelliJ IDEA中,构建项目(?Build +→+ Build Project
?)有同样的效果。
如果使用构建插件,运行Maven的?mvn compile
?或Gradle的?gradle build
?会触发重启。
?
??这时候可能有小伙伴想问了,难道IDEA没有类似于Eclipse中保存文件自动触发重启的功能嘛。那肯定是有的,只需要进行下面两步的配置就可以实现了。
注意:需要将前面的设置,全部还原。
Build project automatically
。Ctrl + Alt + Shift + /
?调出 Registry 窗口,勾选?compiler.automake.allow.when.app.running
?选项。新版本如下图所示:
如果你的应用程序是通过?
java -jar
?启动的,或者是从一个特殊的classloader启动的,那么它就被认为是一个 "生产级别的应用程序",开发者工具会被自动禁用。 你可以通过?spring.devtools.restart.enabled
?配置属性来控制这一行为。 要启用devtools,无论用于启动应用程序的类加载器是什么,请设置启动参数?-Dspring.devtools.restart.enabled=true
?。 在生产环境中不能这样做,因为运行devtools会有安全风险。 要禁用devtools,请删除该依赖或者设置启动参数?-Dspring.devtools.restart.enabled=false
。
如果你不想使用重启功能,你可以通过使用?spring.devtools.restart.enabled
?属性来禁用它。在大多数情况下,你可以在你的 application.properties 中设置这个属性(这样做仍然会初始化restart 类加载器,但它不会监控文件变化)。
如果你需要完全禁用重启支持(例如,因为它不能与特定的库一起工作),你需要在调用?SpringApplication.run(…?)
?之前将?spring.devtools.restart.enabled
?属性设置为 false ,如下面的例子中所示。
Java
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApplication.class, args);
}
}
在Spring Boot支持的一些库中,会使用缓存来提高性能。例如,模板引擎会缓存已编译的模板,以避免重复解析模板文件。另外,Spring MVC可以在响应静态资源时往响应中添加HTTP缓存头。 虽然缓存在生产中是非常有益的,但在开发过程中可能会产生反作用,使你无法看到你在应用程序中刚做的改动。 由于这个原因,spring-boot-devtools 默认禁用了缓存选项。 缓存的选项通常是通过 application.properties 文件中的属性来配置的。 例如,Thymeleaf提供了 spring.thymeleaf.cache[] 属性。 与其需要手动设置这些属性,spring-boot-devtools 模块会在开发场景下合理的设置这些属性。 下表列出了所有被设置的属性。
Name | Default Value |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
你可以通过在?$HOME/.config/spring-boot
?目录下添加以下任何文件来配置全局的devtools设置。
spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml
添加到这些文件中的任何属性都适用于你机器上使用devtools的?所有?Spring Boot应用程序。 例如,? 如果要将重启配置为总是使用trigger file,你可以在?spring-boot-devtools
?文件中添加以下属性。
Yaml
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
默认情况下,$HOME
?是用户的主目录。 要自定义这个位置,请设置?SPRING_DEVTOOLS_HOME
?环境变量或?spring.devtools.home
?系统属性。
Spring Boot的开发者工具并不局限于本地开发。 你也可以在远程运行应用程序时使用一些功能。 远程支持是可选的,因为启用它可能会有安全风险。 只有在受信任的网络上运行时,或在用SSL保护时,才应启用它。 如果这两个选项对你来说都不可用,你就不应该使用DevTools的远程支持。 你更不应该在生产环境中启用它。
要启用它,你需要确保?devtools
?包含在重新打包的归档文件(jar)中,如以下所示。
<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
?属性。 就像任何重要的密码或密钥一样,这个值应该是唯一的和足够强大的,以至于它不能被猜到或被暴力破解。
Remote devtools support is provided in two parts: a server-side endpoint that accepts connections and a client application that you run in your IDE. The server component is automatically enabled when the?spring.devtools.remote.secret
?property is set. The client component must be launched manually.
远程devtools支持由两部分组成:一个接受连接的服务器端端点和一个你在IDE中运行的客户端应用程序。 当?spring.devtools.remote.secret
?属性被设置时,服务器组件会自动启用。 客户端组件必须手动启动。
?