1、热部署是什么?

对于Java应用程序来说,热部署就是在运行时更新Java类文件。
2、热部署有什么用?
可以不重启应用的情况下,更新应用。举个例子,就像电脑可以在不重启的情况下,更换U盘。
OSGI也正是因为它的模块化和热部署,才显得热门。
3、热部署的原理是什么?
想要知道热部署的原理,必须要了解java类的加载过程。一个java类文件到虚拟机里的对象,要经过如下过程。
首先通过java编译器,将java文件编译成class字节码,类加载器读取class字节码,再将类转化为实例,对实例newInstance就可以生成对象。
类加载器ClassLoader功能,也就是将class字节码转换到类的实例。
在java应用中,所有的实例都是由类加载器,加载而来。
一般在系统中,类的加载都是由系统自带的类加载器完成,而且对于同一个全限定名的java类(如com.csiar.soc.HelloWorld),只能被加载一次,而且无法被卸载。
这个时候问题就来了,如果我们希望将java类卸载,并且替换更新版本的java类,该怎么做呢?
     既然在类加载器中,java类只能被加载一次,并且无法卸载。那是不是可以直接把类加载器给换了?答案是可以的,我们可以自定义类加载器,并重写ClassLoader的findClass方法。想要实现热部署可以分以下三个步骤:
1、销毁该自定义ClassLoader
2、更新class类文件
3、创建新的ClassLoader去加载更新后的class类文件。
示例代码如下:
  1. package com.csair.soc.hotswap;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. /**
  6. * 自定义类加载器,并override findClass方法
  7. */
  8. public class MyClassLoader extends ClassLoader{
  9. @Override
  10. public Class<?> findClass(String name) throws ClassNotFoundException{
  11. try{
  12. String fileName = name.substring(name.lastIndexOf("." )+1) + ".class" ;
  13. InputStream is = this.getClass().getResourceAsStream(fileName);
  14. byte[] b = new byte[is.available()];
  15. is.read(b);
  16. return defineClass(name, b, 0, b. length);
  17. } catch(IOException e){
  18. throw new ClassNotFoundException(name);
  19. }
  20. }
  21. }
需要更新的类文件:
  1. package com.csair.soc.hotswap;
  2. public class HelloWorld {
  3. public void say(){
  4. System. out.println( "Hello World V1");
  5. }
  6. }
在工程的根目录下,生成V2版本的HelloWorld.class,内容如下。
  1. package com.csair.soc.hotswap;
  2. public class HelloWorld {
  3. public void say(){
  4. System. out.println( "Hello World V2");
  5. }
  6. }
测试主程序
  1. package com.csair.soc.hotswap;
  2.  
  3. import java.io.File;
  4. import java.lang.reflect.Method;
  5.  
  6. public class Hotswap {
  7. public static void main(String[] args) throws Exception {
  8. loadHelloWorld();
  9. // 回收资源,释放HelloWorld.class文件,使之可以被替换
  10. System. gc();
  11. Thread. sleep(1000);// 等待资源被回收
  12. File fileV2 = new File( "HelloWorld.class");
  13. File fileV1 = new File(
  14. "bin\\com\\csair\\soc\\hotswap\\HelloWorld.class" );
  15. fileV1.delete(); //删除V1版本
  16. fileV2.renameTo(fileV1); //更新V2版本
  17. System. out.println( "Update success!");
  18. loadHelloWorld();
  19. }
  20.  
  21. public static void loadHelloWorld() throws Exception {
  22. MyClassLoader myLoader = new MyClassLoader(); //自定义类加载器
  23. Class<?> class1 = myLoader
  24. .findClass( "com.csair.soc.hotswap.HelloWorld");//类实例
  25. Object obj1 = class1.newInstance(); //生成新的对象
  26. Method method = class1.getMethod( "say");
  27. method.invoke(obj1); //执行方法say
  28. System. out.println(obj1.getClass()); //对象
  29. System. out.println(obj1.getClass().getClassLoader()); //对象的类加载器
  30. }
  31. }
输出结果:
Hello World V1
class com.csair.soc.hotswap.HelloWorld
com.csair.soc.hotswap.MyClassLoader@bfc8e0
Update success!
Hello World V2
class com.csair.soc.hotswap.HelloWorld
com.csair.soc.hotswap.MyClassLoader@860d49
根据结果可以看到,在没有重启应用的情况下,成功的更新了HelloWorld类。
以上只是热部署的最简单的原理实践,实际情况会复杂的多。OSGI的最关键理念就是应用模块(bundle)化,对于每一个bundle,都有其自己的类加载器,当需要更新bundle时,把bundle和它的类加载器一起替换掉,就可以实现模块的热替换。

参考资料

深入理解java虚拟机
深入探讨 Java 类加载器 http://www.ibm.com/developerworks/cn/java/j-lo-classloader/
 

JAVA热部署原理的更多相关文章

  1. 揭秘Java热部署原理及JRebel(Hotcode)的实现原理

    基础知识:class卸载.热替换和Tomcat的热部署的分析HotSwap:HotSwap和JRebel原理成熟的热部署技术实现原理:深入探索 Java 热部署 java的热部署和热加载

  2. springboot热部署(一)——Java热部署与热加载原理

    一.概述 在应用运行的时升级软件,无需重新启动的方式有两种,热部署和热加载. 对于Java应用程序来说, 热部署就是在服务器运行时重新部署项目,——生产环境 热加载即在在运行时重新加载class,从而 ...

  3. 探秘 Java 热部署三(Java agent agentmain)

    前言 让我们继续探秘 Java 热部署.在前文 探秘 Java 热部署二(Java agent premain)中,我们介绍了 Java agent premain.通过在main方法之前通过类似 A ...

  4. 探秘 Java 热部署二(Java agent premain)

    # 前言 在前文 探秘 Java 热部署 中,我们通过在死循环中重复加载 ClassLoader 和 Class 文件实现了热部署的功能,但我们也指出了缺点-----不够灵活.需要手动修改文件等操作. ...

  5. Springboot热部署(热部署原理)和用IDEA开发需要的配置

    热部署原理 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  6. 探秘 Java 热部署

    # 前言 在之前的 深入浅出 JVM ClassLoader 一文中,我们说可以通过修改默认的类加载器实现热部署,但在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能 ...

  7. JAVA热部署,通过agent进行代码增量热替换!!!

    在前说明:好久没有更新博客了,这一年在公司做了好多事情,包括代码分析和热部署替换等黑科技,一直没有时间来进行落地写出一些一文章来,甚是可惜,趁着中午睡觉的时间补一篇介绍性的文章吧. 首先热部署的场景是 ...

  8. IntelliJ IDEA 的 Java 热部署插件 JRebel 安装及使用

    JRebel 介绍 JRebel for Intellij JRebel 在 Java Web 开发中, 一般更新了 Java 文件后要手动重启 Tomcat 服务器, 才能生效,  自从有了 JRe ...

  9. 深入探索 Java 热部署

    在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的应用来 ...

随机推荐

  1. 微信小程序开发教程(四)线程架构与开发步骤

    线程架构 从前面的章节我们可以知道,.js文件是页面逻辑处理层.我们可以按需在app.js和page.js中添加程序在生命周期的每个阶段相应的事件.如在页面的onLoad时进行数据的下载,onShow ...

  2. intellij idea 为JavaEE项目建立Servlet

    建立Servlet的方法 顶部菜单栏 View > Tool Windows > Web. 然后互相web窗口 右键Web>new>Servlet 弹出窗口

  3. 【莫队算法】bzoj3781 小B的询问

    莫队经典. 开个数组维护a[i]出现的次数. #include<cstdio> #include<cmath> #include<algorithm> using ...

  4. cocos2d-x 扩展 修改 备注

    1.引擎源码相关扩展     说明:class/cellsExt 下的全部文件为扩展文件,有auto字样的文件为生成文件,*.pkg文件为自动生成文件的接口配置档,参考tolua++,源文件中代在[s ...

  5. 关于DNS,你应该知道这些

    在互联网时代中,如果要问哪个应用层协议最重要的话,我想答案无疑是DNS.虽然我们每天都享受着DNS服务带来的便利, 却对它往往知之甚少.因此本文就来介绍一下DNS协议的工作流程,真正认识一下这个支撑着 ...

  6. Easyui的numberbox无法输入以0开头的数字编号(转载)

    1.问题 项目中碰到这样一个问题,Easyui的numberbox在输入数字编号的时候不能以0开头 在我输入以0开头的数字编号后,离开输入框的时候,那个前缀0就自动去掉了. 接下来,我们查看API说明 ...

  7. [转载]Oracle Merge的使用

    FROM: http://zhangqchang.blog.163.com/blog/static/464989732009219114653226/ 摘至网上的几个例子 一.************ ...

  8. IDEA默认VIM模式

    Intellij Idea, 每次打开文件都进入了vim模式,必须输入i才可编辑,实在是非常困扰. 终于找到了解决办法:取消Vim Emulator的选择:

  9. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-人机界面快速入门 TC2

    创建最简单的静态文本,就像是label,就只需要绘制一个矩形框,然后填写Text,取消边框即可(你也可以设置自定义字体)   创建动态的文本框,就像是textbox,需要设置这个矩形框的Text为%d ...

  10. Win7如何查看自己得Win7版本号

    如何查看Windows 7详细系统版本号? --Windows 7系统知识100问之七十一 责任编辑:姜惠田作者:IT168 老姜   2009-08-05 前言:微软新一代操作系统Windows 7 ...