Spring Boot热部署的实现
一、 热部署和热加载的区别1.定义区别热部署:是指在服务器运行时重新部署项目热加载:是指在运行时重新加载class2.实现原理区别热部署:直接重新加载整个应用,会直接释放内存,比热加载更加干净彻底,但是浪费时间;热加载:在运行时重新加载class,依赖java的内加载机制,在容器启动时后台起一个线程用于定时检测类文件的时间戳的变化,如果时间戳变化了则加载最新的class;
一、 热部署和热加载的区别
1.定义区别
热部署:是指在服务器运行时重新部署项目
热加载:是指在运行时重新加载class
2.实现原理区别
热部署:直接重新加载整个应用,会直接释放内存,比热加载更加干净彻底,但是浪费时间;
热加载:在运行时重新加载class,依赖java的内加载机制,在容器启动时后台起一个线程用于定时检测类文件的时间戳的变化,如果时间戳变化了则加载最新的class;
3.Java类的热部署
两种方式:
1.类的热加载
1.自定义类类加载器,通过继承java.lang.ClassLoader,重写其中的findClass方法,一旦发现字节码立刻调用defineClass方法,主要代码如下:
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
System.out.println("加载类===" + name);
byte[] data = loadClassData(name);
return this.defineClass(name, data, 0,data.length);
}
2. 配置Tomcat
通过配置Tomcat实现热部署,三种方式:
- 直接将项目web文件夹放到Tomcat的webapps目录下即可;
这种方式就是使用的Tomcat自带的热部署实现的
2.在Tomcat\conf\server.xml文件中的<host></host>内部添加<context/>标签;
<Context debug="0" docBase="D:/Test/Hotweb" path="/hot" privileged="true" reloadable="true"/>
其中docBase是指Tomcat热部署的文件夹(即将项目的中的文件夹(不包括项目的根目录,正常就是META-INF和WEB-INF两个文件夹)丢到这个目录下面即可),path是配置了虚拟访问路径,这时候就不能通过访问webapp来访问项目了,并且在访问路径下需要加上/hot,即localhost:8080/hot/…
3.在Tomcat\conf\Catalina\localhost目录下添加一个xml文件作为它一部分路径来访问.
比如在该目录下面创建hot.xml文件,其中的内容为
<?xml Version="1.0" encoding="UTF-8">
<Context docBase="D:/Test/Hotweb" reloadable="true"/>
4.java类热加载的是实例
这里跑测试程序ClassLoaderTest时,注意使用debug模式(如果需要直接Run as java application则需要更改MannagerFactory中的loadClass = myClassloader.findClass(MY_MANAGER);改为loadClass = myClassloader.loadClass(className);),否则无法实现热加载,Eclipse需要开启自动编译的功能,可以改变MyMannager类中的打印内容查看控制台的输出是否改变来验证热加载是否成功。主要代码如下:
package com.hhu.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
/**
* 自定义类加载器来是实现java类的热加载
* 继承java.lang.ClassLoader,重写其中
* 的findClass方法
*
* @author Weiguo Liu
* @data 2017年11月29日
*/
public class MyClassloader extends ClassLoader {
//要加载的Java类的classpath路径
private String classpath;
public MyClassloader(String classpath) {
super(ClassLoader.getSystemClassLoader());
this.classpath = classpath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// TODO Auto-generated method stub
byte[] data = this.loadClassData(name);
return super.defineClass(name, data, 0, data.length);
}
/*
* 记载class文件中的内容
*/
private byte[] loadClassData(String name) {
try {
//因为包名包含.要将它替换成//
name = name.replace(".", "//");
//文件输入流
FileInputStream is =new FileInputStream(new File(classpath + name + ".class"));
//字节数组输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b = 0;
while((b=is.read())!=-1) {
baos.write(b);
}
is.close();
return baos.toByteArray();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
}
完整工程见:https://github.com/Jacksonary/CodeRepository/tree/master/classloader
二、SpringBoot热部署的实现
主要有两种方式:1.使用Spring Loaded 2.使用Spring-boot-devtools
1.SpringLoaded热部署的实现(未实现)
(1)第一种方式:Maven启动方式
在pom.xml中添加Springloaded依赖,这种方式必须使用Maven指令启动:mvn spring-boot:run
在dos窗口下,进入工程目录运行上述命令即可,也可以直接在Eclipse中,Run As–>maven build…->在Goals中填写spring-boot:run。
这种方法我测试没有通过,还没找到原因
<!--引入spring-boot热部署的依赖,这种方式必须使用maven启动 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
(2)第二种方式:也可以Run As -->Java Application来实现
需要下载一个Springloaded的jar包,放在自己笔记本的任意目录下即可,然后右击Run Configuration,在Springboot下一栏中找到对应的Application点击Arguments,在VM一栏中填写如下
2.Spring-boot-devtools热部署(可实现)
直接在pom.xml中添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
更多推荐
所有评论(0)