Spring boot实现热部署的两种方式详解

热部署是什么

大家都知道在项目开发过程中,常常会改动页面数据或者修改数据结构,为了显示改动效果,往往需要重启应用查看改变效果,其实就是重新编译生成了新的 Class 文件,这个文件里记录着和代码等对应的各种信息,然后 Class 文件将被虚拟机的 ClassLoader 加载。

而热部署正是利用了这个特点,它监听到如果有 Class 文件改动了,就会创建一个新的 ClaassLoader 进行加载该文件,经过一系列的过程,最终将结果呈现在我们眼前。

类加载机制

Java 中的类经过编译器可以把代码编译为存储字节码的 Class 文件,该 Class 文件存储了各种信息,最终要加载到虚拟机中运行使用。

类加载机制(摘自《深入理解 Java 虚拟机》)

虚拟机把描述类的数据从 Class 文件加载到内存中,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型。

Spring Boot 实现热部署

Spring Boot 实现热部署很简单,我们使用上一章创建的项目 Springboot 创建简单的 web 交互应用 来演示。

springloaded

在 POM 文件中添加依赖

<build>
 <plugins>
 <plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <dependencies>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>springloaded</artifactId>
    <version>1.2.6.RELEASE</version>
   </dependency>
  </dependencies>
 </plugin>
 </plugins>
</build>

添加完毕,启动项目

Note

这次启动不能直接运行 main 方法了,需要使用
mvn spring-boot:run 启动,然后随意在代码中写一个 System.out.println("Hi") ,再次调用那个方法,会发现控制台会打印出 Hi。

spring-boot-devtools

添加 POM 文件依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-devtools</artifactId>
 <optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
</dependency>

然后还是使用 mvn spring-boot:run 启动项目,随意更改代码即可看到效果。

如果我们想指定让 devtools 监听指定文件夹,那么可以在 application.yml 配置
spring.devtools.restart.additional-paths=your path,注意这里需要改成 yml 文件的格式。

Important(特别注意)

可能会有同学按照以上方法处理了都无效。

这里要特别注意下:由于热部署是监听 Class 文件的变化,它自身不会主动去编译 Java 文件,所以我们得在 Java 文件改动时,自动编译成 Class 文件,然后热部署工具创造的新的类加载器才会加载改变后的 Class 文件。

所以,如果你使用 IDEA 开发工具的话,记得要把自动编译打开。

如图打钩即可。

由于热部署的时候是产生了新的类加载器,我们的一个类可能在虚拟机中存在两个类,比如代码中就一个 User 类,但是虚拟机中会存在两个 User ,虽然是同一个 Class 文件,但是却是两个独立的类,这个要清楚。

由于第一次使用热部署,一开始遇到个很奇怪的问题,A instanceof A == false,明明两个 A.getClass() 都一样,但结果就是 false,还问了几个朋友,表示都没遇到,后来当我把 devtools 依赖注释后,才正确执行。

如果有遇到类似问题的朋友,可以检查下是不是由于不同的 ClassLoader 造成的。

本系列所有代码已同步到 GitHub, 项目地址 github:sboot-learn,大家也可以通过本地进行下载。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 详解Spring Boot 部署与服务配置

    spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项目打包成war包,放到独立的web容器中(Tomcat.weblogic等等),当然在此之前你要对程序入口做简单调整. 项目构建我们使用Maven或Gradle,这将使项目依赖.jar包管理.以及打包部署变的非常方便. 一.内嵌 Server 配置 Spring Boot将容器内置后,它通过配置文件

  • 详解SpringBoot配置devtools实现热部署

    spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. devtools的原理 深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为restart ClassLoader,这样在有代码更改的时候,原来的restart ClassLoader 被丢弃,重新创建一个r

  • springboot + devtools(热部署)实例教程

    技术介绍 devtools:是boot的一个热部署工具,当我们修改了classpath下的文件(包括类文件.属性文件.页面等)时,会重新启动应用(由于其采用的双类加载器机制,这个启动会非常快,如果发现这个启动比较慢,可以选择使用jrebel) 双类加载器机制:boot使用了两个类加载器来实现重启(restart)机制:base类加载器(简称bc)+restart类加载器(简称rc). bc:用于加载不会改变的jar(eg.第三方依赖的jar) rc:用于加载我们正在开发的jar(eg.整个项目里

  • Spring Boot应用的极速部署脚本示例代码

    前言 本文主要给大家介绍了关于Spring Boot应用极速部署脚本的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 部署方法如下: 在 pom.xml 路径下新建文件 start.sh #!/bin/bash #0.删除原有的日志文件 rm -f nohup.out #1.获取正在运行的 Spring Boot 应用的 pid appPid=`netstat -ntlp | grep java | awk '{print $7}' | head -1 | grep

  • Spring boot 基本部署方式

    String boot 部署 SpringBoot部署也是非常简单,首先,需要把打包输出的包由jar改为war,即修改pom.xml中packaging节点: <packaging>war</packaging> 然后,修改pom.xml类,新增依赖: tomcat依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-s

  • 使用Docker部署 spring-boot maven应用的方法

    本文介绍了使用Docker部署 spring-boot maven应用,分享给大家,具体如下: 部署过程分为以下几个步骤: 创建一个简单的spring-boot应用 打包运行应用 容器化应用 在pom文件中添加docker支持 创建docker镜像 运行docker容器 查看正在运行的容器 启动/关闭/重启/删除docker容器 1. 创建一个简单的spring-boot应用 在IntelliJ IDEA中File->New->Project: 然后点Next->Finish. 2. 打

  • SpringBoot 创建web项目并部署到外部Tomcat

    前言 使用SpringBoot来开发项目相对于传统模式,要快速优雅许多,相信目前国内绝大部分web项目的开发还没有使用SpringBoot来做,如果你正需要开发一个web项目,不妨尝试使用SpringBoot来做. 本身SpringBoot是内嵌了web服务器,不需要单独的Tomcat,但是实际生产环境中,如果是web项目,Tomcat肯定是运维部门部署好了的,这个Tomcat,做了一些个性化的设置,开发出来的项目需要部署到这个Tomcat,如果是使用SpringBoot开发web服务,我认为可

  • 如何把spring boot项目部署到tomcat容器中

    把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 <packaging>war</packaging> 二.移除嵌入式tomcat插件 在pom.xml里找到spring-boot-starter-web依赖节点,在其中添加如下代码, <dependency> <groupId>org.springframework.boot</groupId> <artifactId&

  • 详解springboot热启动与热部署

    一.热启动: 每自修改后, 程序自动启动spring Application上下文. Pom中直接添加依赖即可: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> 这里需要注意的

  • Spring boot实现热部署的两种方式详解

    热部署是什么 大家都知道在项目开发过程中,常常会改动页面数据或者修改数据结构,为了显示改动效果,往往需要重启应用查看改变效果,其实就是重新编译生成了新的 Class 文件,这个文件里记录着和代码等对应的各种信息,然后 Class 文件将被虚拟机的 ClassLoader 加载. 而热部署正是利用了这个特点,它监听到如果有 Class 文件改动了,就会创建一个新的 ClaassLoader 进行加载该文件,经过一系列的过程,最终将结果呈现在我们眼前. 类加载机制 Java 中的类经过编译器可以把代

  • Spring Boot实现热部署的五种方式

    1.模板热部署 在 Spring Boot 中,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.properties中关闭模版引擎的缓存,如下:Thymeleaf的配置: spring.thymeleaf.cache=false FreeMarker的配置: spring.freemarker.cache=false Groovy的配置: spring.groovy.template.cache=false Veloc

  • 详解Spring Boot 中实现定时任务的两种方式

    在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具备这两个 Spring 中的定时任务实现策略,当然也支持 Quartz,本文我们就来看下 Spring Boot 中两种定时任务的实现方式. @Scheduled 使用 @Scheduled 非常容易,直接创建一个

  • spring boot ajax跨域的两种方式

    前言 java语言在多数时,会作为一个后端语言,为前端的php,node.js等提供API接口.前端通过ajax请求去调用java的API服务.今天以node.js为例,介绍两种跨域方式:CrossOrigin和反向代理.  一.准备工作 pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0&quo

  • Spring boot调用Oracle存储过程的两种方式及完整代码

    前言 因工作需要将公司SSH项目改为Spingboot项目,将项目中部分需要调用存储过程的部分用entityManagerFactory.unwrap(SessionFactory.class).openSession()来获取Session实现后发现项目访问数据库超过十次就会挂掉,原因是Springboot连接池数量默认为10,猜测是每次访问数据库后连接未释放导致的,手动关闭session后问题解决. 解决问题的过程中又发现了另外两种调用方式: 直接用EntityManager的createS

  • Spring Bean属性注入的两种方式详解

    目录 属性注入概念 一.构造器注入 示例1 注意点 二.setter注入 示例2 三.如何选择注入方式 属性注入概念 Spring 属性注入(DI依赖注入)有两种方式:setter注入,构造器注入. 这个注入的属性可以是普通属性(基本数据类型与String等),也可以是一个引用数据类型(主要是对象),或者是一个集合(list.map.set等) 下表是属性注入bean标签中常用的元素 元素名称 描述 constructor-arg 构造器注入.该元素的 index 属性指定构造参数的索引(从 0

  • Spring框架实现AOP的两种方式详解

    目录 第一种AOP实现方式 AfterLog Log 配置文件 实例调用 定义接口 第二种AOP实现方式 第一种AOP实现方式 AfterLog package com.xxx.demo.service1; import org.junit.After; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; public class AfterLog implements Aft

  • springboot 注册服务注册中心(zk)的两种方式详解

    在使用springboot进行开发的过程中,我们经常需要处理这样的场景:在服务启动的时候,需要向服务注册中心(例如zk)注册服务状态,以便当服务状态改变的时候,可以故障摘除和负载均衡. 我遇到过两种注册的途径: 1.在Spring的webapplication启动完成后,直接进行注册: 2.在servlet容器启动完成后,通过listener进行注册. 本文通过一个demo讲述一下这两种注册方式,使用的是传统的向zk注册的方案. 1.Spring webapplication启动完成后注册 先上

  • RabbitMQ 实现延迟队列的两种方式详解

    目录 1. 用插件 1.1 安装插件 1.2 消息收发 2. DLX 实现延迟队列 2.1 延迟队列实现思路 2.2 案例 3. 小结 定时任务各种各样,常见的定时任务例如日志备份,我们可能在每天凌晨 3 点去备份,这种固定时间的定时任务我们一般采用 cron 表达式就能轻松的实现,还有一些比较特殊的定时任务,向大家看电影中的定时炸弹,3分钟后爆炸,这种定时任务就不太好用 cron 去描述,因为开始时间不确定,我们开发中有的时候也会遇到类似的需求,例如: 在电商项目中,当我们下单之后,一般需要

  • mapper接口注入两种方式详解

    这篇文章主要介绍了mapper接口注入两种方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.使用模板方式: <!--使用模板类实现mybatis --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg name="sqlSessionFacto

随机推荐