springboot-热部署

什么是热部署

事先我创建一个springboot项目。

主程序代码如下: 

import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
  
@SpringBootApplication  
public class MySpringBootApplication {  
  
    private static final Logger logger = LoggerFactory.getLogger(MySpringBootApplication.class);  
  
    public static void main(String[] args) {  
        long startTime = System.currentTimeMillis();  
  
        SpringApplication.run(MySpringBootApplication.class, args);  
  
        long endTime = System.currentTimeMillis();  
        long startupTime = endTime - startTime;  
  
        logger.info("Spring Boot application started in {} milliseconds", startupTime);  
    }  
}

当我冷启动的时候,日志如下:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v2.6.13)

2024-02-27 20:53:57.318  INFO 8368 --- [           main] c.z.helloworld2.MySpringBootApplication  : Starting MySpringBootApplication using Java 1.8.0_201 on B515-54 with PID 8368 (D:\Eclipse_Project\lx\helloworld2\target\classes started by user in D:\Eclipse_Project\lx\helloworld2)
2024-02-27 20:53:57.320  INFO 8368 --- [           main] c.z.helloworld2.MySpringBootApplication  : No active profile set, falling back to 1 default profile: "default"
2024-02-27 20:53:58.044  INFO 8368 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8090 (http)
2024-02-27 20:53:58.045  INFO 8368 --- [           main] o.a.catalina.core.AprLifecycleListener   : An older version [1.2.21] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [1.2.30]
2024-02-27 20:53:58.045  INFO 8368 --- [           main] o.a.catalina.core.AprLifecycleListener   : Loaded Apache Tomcat Native library [1.2.21] using APR version [1.6.5].
2024-02-27 20:53:58.045  INFO 8368 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [false].
2024-02-27 20:53:58.045  INFO 8368 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2024-02-27 20:53:58.048  INFO 8368 --- [           main] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1a  20 Nov 2018]
2024-02-27 20:53:58.057  INFO 8368 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-02-27 20:53:58.057  INFO 8368 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.68]
2024-02-27 20:53:58.156  INFO 8368 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-02-27 20:53:58.157  INFO 8368 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 795 ms
2024-02-27 20:53:58.361  INFO 8368 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2024-02-27 20:53:58.426  INFO 8368 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8090 (http) with context path ''
2024-02-27 20:53:58.433  INFO 8368 --- [           main] c.z.helloworld2.MySpringBootApplication  : Started MySpringBootApplication in 1.413 seconds (JVM running for 1.683)
2024-02-27 20:53:58.435  INFO 8368 --- [           main] c.z.helloworld2.MySpringBootApplication  : Spring Boot application started in 1540 milliseconds

从打印日志看,花费1540毫秒。

然后我让程序实现热部署,关闭再启动,日志如下:

20:56:32.539 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@274cb5b1

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v2.6.13)

2024-02-27 20:56:32.820  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : Starting MySpringBootApplication using Java 1.8.0_201 on B515-54 with PID 8872 (D:\Eclipse_Project\lx\helloworld2\target\classes started by user in D:\Eclipse_Project\lx\helloworld2)
2024-02-27 20:56:32.821  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : No active profile set, falling back to 1 default profile: "default"
2024-02-27 20:56:32.871  INFO 8872 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2024-02-27 20:56:32.871  INFO 8872 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2024-02-27 20:56:33.663  INFO 8872 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8090 (http)
2024-02-27 20:56:33.664  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : An older version [1.2.21] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [1.2.30]
2024-02-27 20:56:33.664  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : Loaded Apache Tomcat Native library [1.2.21] using APR version [1.6.5].
2024-02-27 20:56:33.664  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [false].
2024-02-27 20:56:33.664  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2024-02-27 20:56:33.667  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1a  20 Nov 2018]
2024-02-27 20:56:33.678  INFO 8872 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-02-27 20:56:33.678  INFO 8872 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.68]
2024-02-27 20:56:33.729  INFO 8872 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-02-27 20:56:33.729  INFO 8872 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 858 ms
2024-02-27 20:56:33.951  INFO 8872 --- [  restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2024-02-27 20:56:34.011  INFO 8872 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2024-02-27 20:56:34.034  INFO 8872 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8090 (http) with context path ''
2024-02-27 20:56:34.041  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : Started MySpringBootApplication in 1.495 seconds (JVM running for 1.803)
2024-02-27 20:56:34.043  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : Spring Boot application started in 1501 milliseconds

这时花费1501毫秒。然后我修改启动类,日志如下:

2024-02-27 20:58:05.615  INFO 8872 --- [   File Watcher] rtingClassPathChangeChangedEventListener : Restarting due to 1 class path change (0 additions, 0 deletions, 1 modification)
2024-02-27 20:58:05.685  INFO 8872 --- [       Thread-6] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v2.6.13)

2024-02-27 20:58:05.771  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : Starting MySpringBootApplication using Java 1.8.0_201 on B515-54 with PID 8872 (D:\Eclipse_Project\lx\helloworld2\target\classes started by user in D:\Eclipse_Project\lx\helloworld2)
2024-02-27 20:58:05.772  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : No active profile set, falling back to 1 default profile: "default"
2024-02-27 20:58:05.906  INFO 8872 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8090 (http)
2024-02-27 20:58:05.906  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : An older version [1.2.21] of the Apache Tomcat Native library is installed, while Tomcat recommends a minimum version of [1.2.30]
2024-02-27 20:58:05.906  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : Loaded Apache Tomcat Native library [1.2.21] using APR version [1.6.5].
2024-02-27 20:58:05.906  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [false].
2024-02-27 20:58:05.906  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2024-02-27 20:58:05.906  INFO 8872 --- [  restartedMain] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1a  20 Nov 2018]
2024-02-27 20:58:05.907  INFO 8872 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-02-27 20:58:05.907  INFO 8872 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.68]
2024-02-27 20:58:05.914  INFO 8872 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-02-27 20:58:05.915  INFO 8872 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 141 ms
2024-02-27 20:58:05.953  INFO 8872 --- [  restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2024-02-27 20:58:05.973  INFO 8872 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2024-02-27 20:58:05.978  INFO 8872 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8090 (http) with context path ''
2024-02-27 20:58:05.980  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : Started MySpringBootApplication in 0.229 seconds (JVM running for 93.739)
2024-02-27 20:58:05.982  INFO 8872 --- [  restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged
2024-02-27 20:58:05.982  INFO 8872 --- [  restartedMain] c.z.helloworld2.MySpringBootApplication  : Spring Boot application started in 233 milliseconds

花费233毫秒。 

分析如下:

热部署始终使用同一个进程,冷启动创建一个新的进程。在热部署例子中,修改了两个类,但类路径上是先删除后增加两个字节码文件,导致两次热部署,但明显用时比冷启动要短。在类路径上删除启动类字节码后,热部署时不会删除它,要是删除它,应用就运行不了,但删除controller类字节码后,热部署时spring容器就会删除它,导致某段时间访问时,出现404。

结论:

热部署就是重启:自定义开发代码,包括类、页面、配置文件等,加载位置是restart类加载器,如下:

18:22:39.453 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@316ec5b4

 冷启动的话还包括重载:jar包,加载位置是base类加载器。 

如何实现热部署

springboot使用内嵌的Tomcat,Tomcat也是spring容器的一个对象,那么这个对象如何知道自定义代码发生了变化?需要有个工具帮助它,如下:

在pom文件中添加spring-boot-devtools热部署依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

手动热部署:

build-》build project,激活热部署

自动热部署:

设置自动构建

eclipse:

idea:

IDEA配置热部署_idea热部署配置_微风粼粼的博客-CSDN博客

1、file-》settings-》build..-》compiler->build project automatically

2、ctrl+Alt+shift+/ ->registry...->选中compiler.automake.allow.when.app.running(如果存在)  

激活方式:焦点离开idea 5秒后 重启

热部署测试

修改HelloController的方法的返回值

热部署配置范围

默认不触发重启的目录列表

/META-INF/maven

/META-INF/resources

/resources

/static

/public

/templates

设置不触发重启的项

spring.devtools.restart.exclude=config/application.properties,static/**

禁用热部署

spring.devtools.restart.enabled=false

由于其他人也会通过配置启用热部署,导致自己的配置失效,那么我们可以在更高一层配置。

先看下属性加载优先顺序(由低到高)
参看 https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config

 我们可以通过第六级完成更高一层的配置

@SpringBootApplication
public class HotStartApplication {

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled","false");
        SpringApplication.run(HotStartApplication.class, args);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值