package test;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel; public class DynamicLoader extends ClassLoader { private String baseDir; public DynamicLoader(String baseDir) {
super();
this.baseDir = baseDir;
} private String getClassFile(String className){
return baseDir+className.replace(".", "/")+".class";
} protected Class findClass(String className) throws ClassNotFoundException {
Class clazz = this.findLoadedClass(className);
if (null == clazz) {
try {
String classFile = getClassFile(className);
FileInputStream fis = new FileInputStream(classFile);
FileChannel fileC = fis.getChannel();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
WritableByteChannel outC = Channels.newChannel(baos);
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
int count = 0;
while ((count = fileC.read(buffer)) > 0) {
buffer.flip();
outC.write(buffer);
buffer.clear();
}
fis.close();
byte[] bytes = baos.toByteArray();
clazz = defineClass(className, bytes, 0, bytes.length);
} catch (Exception e) {
System.out.println("can not load class "+className +" from DynamicLoader.");
}
}
return clazz;
} protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
// First, check if the class has already been loaded
Class re=findClass(name);
if(re==null){
return super.loadClass(name,resolve);
}
return re;
} }
package test;

public class Worker {

    public void doit(){
System.out.println("I am version 3");
}
}
package test;

import java.lang.reflect.Method;

public class HelloMain {

    public static void main(String[] args) throws Exception {

        while(true)
{
DynamicLoader loader = new DynamicLoader("F:\\workspace\\HibernateSrc\\bin\\");
Class clazz = loader.loadClass("test.Worker");
Object instance = clazz.newInstance();
Method doit = clazz.getDeclaredMethod("doit",null);
doit.invoke(instance, null);
Thread.sleep(2000);
} } }

思路:

在HelloMain里面定时的创建新的自定义ClassLoader,然后指定加载某个目录的class文件.加载的时候不是父类优先,而是子类优先模式.

自定义的ClassLoader找到Worker类后,反射穿件实例.

这里不能用new关键字在HelloMain类里面创建Worker实例,也能让反射生成的实例转型成Worker类型,因为那样会导致AppliationClassLoader加载Worker类.

如果被AppliationClassLoader加载了Worker类,那么新版本的Worker就不能再被Application ClassLoader加载了,一个ClassLoader里面同名的class只能有一个.

如果这个时候让AppliationClassLoader加载了老的Worker类,在替换的时候让自定义ClassLoader加载新版本的Woker类,则会出现ClassCastException.

因为这些Worker类来之不同的ClassLoader,比如下面代码会报ClassCastException.

DynamicLoader loader = new DynamicLoader("F:workspaceHibernateSrcbin");

Class clazz = loader.loadClass("test.Worker");

Worker instance = (Worker)clazz.newInstance();//ClassCastException error
instance.doit();

所以Worker类只能是让自定义的ClassLoader加载.同时下次要运行的时候,也要在创建一个新的自定义ClassLoader来加载.

参考 http://www.cnblogs.com/princessd8251/articles/3967569.html

Java实现热替换的更多相关文章

  1. Java 类的热替换---转载

    构建基于 Java 的在线升级系统 Java ClassLoader 技术剖析 在本文中,我们将不对 Java ClassLoader 的细节进行过于详细的讲解,而是关注于和构建在线升级系统相关的基础 ...

  2. Java 类的热替换 —— 概念、设计与实现

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp71   Java 类的热替换 -- 概念.设计与实现 构建基于 Java ...

  3. Java_类的热替换

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/#ibm-pcon Java ClassLoader 技术剖析 在本文中,我们 ...

  4. java中的动态加载和热替换

    https://blog.csdn.net/u010833547/article/details/54312052 ****************************************** ...

  5. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...

  6. 使用自己的ClassLoader实现热替换

    首先实现一个自己的ClassLoader,该ClassLoader重写findClass方法. 从classpath中加载类资源. 注意,不要重写loadClass方法.  因为在使用自定义的MyCl ...

  7. 【转】class卸载、热替换和Tomcat的热部署的分析

    这篇文章主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class的卸载的原理.一 class的热替换ClassLoader中重要的方法 loadClass ...

  8. class卸载、热替换和Tomcat的热部署的分析

    一 class的热替换 ClassLoader中重要的方法 loadClassClassLoader.loadClass(...) 是ClassLoader的入口点.当一个类没有指明用什么加载器加载的 ...

  9. 【JRebel 作者出品--译文】Java class 热更新:关于对象,类,类加载器

    一篇大神的译文,勉强(嗯..相当勉强)地放在类加载器系列吧,第8弹: 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证) 还是Tomcat,关于类加载器的趣味实验 了不得,我可能发现 ...

随机推荐

  1. ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) ERROR 2013 (HY00 ...

  2. kvm安装

    基础环境: 192.168.1.67                  super67 硬件cpu需要支持:Intel VT-x 技术 本实验使用虚拟机VMware Workstation上的虚拟机 ...

  3. 结合自己的程序对thinkphp模板常量的理解

    先上个图,有时候路径很多,没理解会搞混,看手册的说明 页面login.html模板的访问路径为http://www.tp.com/index.php/admin/Manager/login,测试他的常 ...

  4. npm 国内淘宝镜像cnpm

    某些插件很奇怪,需要用国内的镜像下载才可以 #安装淘宝镜像npm install cnpm -g --registry=https://registry.npm.taobao.org #使用淘宝镜像下 ...

  5. 我对Java的java.lang.Class这个类的深入理解

    类是对同一类事物的描述,字段具体的值只有到类实例化时才会指定,静态字段除外.所有的类也是同一类事物,用Class这个类来描述.Class类与String.Person等类是同一个级别的.java的字节 ...

  6. [听听音乐]love is blue

    在朋友圈里听到这首歌,好像是中央台天气预报用过的背景音乐.百度了一下,大致如下: 1967年,在维也纳举行的欧洲电视歌唱大赛,卢森堡歌手薇基·琳德洛丝(Vicky Leandros)演唱了一首由彼埃尔 ...

  7. VNC与Windows之间的复制粘贴

    假设目标主机是Linux,终端主机是Windows(就是在Windows上使用VNC登陆Linux): 在Linux中执行: vncconfig -nowin& 在Linux选中文字后,无需其 ...

  8. Error when loading the SDK:

    android环境搭建:http://www.cnblogs.com/xdp-gacl/p/4322165.html eclipse启动,报了错.  解决: 从安装的android-sdk目录下的to ...

  9. PHP学习(一)----变量及字符串

    PHP中的变量: 1. 定义:$符号来定义变量 2. 说明: (1)PHP弱语言,定义变量的时候不用声明类型,但是并不代表PHP没有数据类型 (2)变量名是区分大小写的,只能是数字,字母或者下划线 ( ...

  10. Decoder with 3 Inputs and 2 3 = 8 Outputs

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION