更新时间:2022-07-07 12:12:33 来源:极悦 浏览2772次
极悦小编来为大家介绍Java热部署的原理。
对于Java应用来说,热部署就是在运行时更新Java类文件。
您可以在不重新启动应用程序的情况下更新应用程序。比如电脑不用重启就可以更换U盘。
OSGI 也因其模块化和热部署而广受欢迎。
要知道热部署的原理,就必须了解java类的加载过程。一个java类文件到虚拟机中的一个对象必须经过以下过程。
通过java编译器,将java文件编译成类字节码,类加载器读取类字节码,然后将类转化为实例,可以为实例newInstance生成一个对象。
ClassLoader 的作用是将类字节码转换为类的实例。
在 Java 应用程序中,所有实例都由类加载器加载。
一般在系统中,类的加载是由系统自带的类加载器完成的,对于同名的java类(如com.csiar.soc.HelloWorld),只能加载一次并且无法加载。卸载。
这时,问题来了。如果我们要卸载java类并替换较新版本的java类,我们应该怎么做呢?
由于在类加载器中,java类只能加载一次,不能卸载。是否可以直接更改类加载器?答案是肯定的,我们可以自定义类加载器,重写ClassLoader的findClass方法。实现热部署可以分为以下三个步骤:
(1)销毁自定义的ClassLoader
(2)更新类文件
(3)新建一个ClassLoader来加载更新的类文件。
示例代码如下:
package com.csair.soc.hotswap;
import java.io.IOException;
import java.io.InputStream;
/**
* Custom class loader, and override the findClass method
*/
public class MyClassLoader extends ClassLoader{
@Override
public Class<?> findClass(String name) throws ClassNotFoundException{
try{
String fileName = name.substring(name.lastIndexOf("." )+1) + ".class";
InputStream is = this.getClass().getResourceAsStream(fileName);
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b. length);
} catch(IOException e){
throw new ClassNotFoundException(name);
}
}
}
需要更新的类文件:
package com.csair.soc.hotswap;
public class HelloWorld {
public void say(){
System. out.println( "Hello World V1");
}
}
在项目根目录下,生成V2版本的HelloWorld.class,内容如下。
package com.csair.soc.hotswap;
public class HelloWorld {
public void say(){
System. out.println( "Hello World V2");
}
}
测试主程序
package com.csair.soc.hotswap;
import java.io.File;
import java.lang.reflect.Method;
public class Hotswap {
public static void main(String[] args) throws Exception {
loadHelloWorld();
//Recycle resources and release the HelloWorld.class file so that it can be replaced
System. gc();
Thread. sleep(1000);//Waiting for resources to be recycled
File fileV2 = new File( "HelloWorld.class");
File fileV1 = new File(
"bin\\com\\csair\\soc\\hotswap\\HelloWorld.class" );
fileV1.delete();//Delete the V1 version
fileV2.renameTo(fileV1);//Update V2 version
System. out.println( "Update success!");
loadHelloWorld();
}
public static void loadHelloWorld() throws Exception {
MyClassLoader myLoader = new MyClassLoader();//Custom class loader
Class<?> class1 = myLoader
.findClass( "com.csair.soc.hotswap.HelloWorld");//Class instance
Object obj1 = class1.newInstance();//Generate a new object
Method method = class1.getMethod( "say");
method.invoke(obj1);//Execute method say
System. out.println(obj1.getClass());//Object
System. out.println(obj1.getClass().getClassLoader());//Object class loader
}
}
输出结果:
你好世界V1
com.csair.soc.hotswap.HelloWorld 类
com.csair.soc.hotswap.MyClassLoader@bfc8e0
更新成功!
你好世界V2
com.csair.soc.hotswap.HelloWorld 类
com.csair.soc.hotswap.MyClassLoader@860d49
根据结果,我们可以看到 HelloWorld 类更新成功,无需重新启动应用程序。如果大家想了解更多相关知识,可以关注一下极悦的Java极悦在线学习,里面的课程内容从入门到精通,细致全面,很适合0基础的小伙伴学习,希望对大家能够有所帮助。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习