专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java热部署的原理

Java热部署的原理

更新时间:2022-07-07 12:12:33 来源:动力节点 浏览2638次

动力节点小编来为大家介绍Java热部署的原理。

1.什么是热部署?

对于Java应用来说,热部署就是在运行时更新Java类文件。

2.热部署有什么用?

您可以在不重新启动应用程序的情况下更新应用程序。比如电脑不用重启就可以更换U盘。

OSGI 也因其模块化和热部署而广受欢迎。

3.热部署的原理是什么?

要知道热部署的原理,就必须了解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基础的小伙伴学习,希望对大家能够有所帮助。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>