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实现热替换的更多相关文章
-
Java 类的热替换---转载
构建基于 Java 的在线升级系统 Java ClassLoader 技术剖析 在本文中,我们将不对 Java ClassLoader 的细节进行过于详细的讲解,而是关注于和构建在线升级系统相关的基础 ...
-
Java 类的热替换 —— 概念、设计与实现
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp71 Java 类的热替换 -- 概念.设计与实现 构建基于 Java ...
-
Java_类的热替换
转自:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/#ibm-pcon Java ClassLoader 技术剖析 在本文中,我们 ...
-
java中的动态加载和热替换
https://blog.csdn.net/u010833547/article/details/54312052 ****************************************** ...
-
透过现象看本质:Java类动态加载和热替换
摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...
-
使用自己的ClassLoader实现热替换
首先实现一个自己的ClassLoader,该ClassLoader重写findClass方法. 从classpath中加载类资源. 注意,不要重写loadClass方法. 因为在使用自定义的MyCl ...
-
【转】class卸载、热替换和Tomcat的热部署的分析
这篇文章主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class的卸载的原理.一 class的热替换ClassLoader中重要的方法 loadClass ...
-
class卸载、热替换和Tomcat的热部署的分析
一 class的热替换 ClassLoader中重要的方法 loadClassClassLoader.loadClass(...) 是ClassLoader的入口点.当一个类没有指明用什么加载器加载的 ...
-
【JRebel 作者出品--译文】Java class 热更新:关于对象,类,类加载器
一篇大神的译文,勉强(嗯..相当勉强)地放在类加载器系列吧,第8弹: 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证) 还是Tomcat,关于类加载器的趣味实验 了不得,我可能发现 ...
随机推荐
-
sql 中 in与exists的对比
1.exists只能用于子查询,可以替代IN,如果查询到结果则退出内部查询,并将条件标记为TRUE,传回全部结果资料 in 不管匹配到匹配不到,都全部匹配 2.根据上面的解释可以得出结论:如果子查询结 ...
-
Spring In Action ③
第三章 最小化Spring xml配置 自动装配(autowiring) 自动检测(autodiscovery) 自动装配 byName.byType.constructor autodetec ...
-
《JavaScript语言精粹》学习笔记
一.in的用法 for...in 枚举一个对象的所有可枚举属性 检测DOM/BOM属性 if ("onclick" in elem) { // 元素支持onclick } if ( ...
-
bnuoj 25659 A Famous City (单调栈)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=25659 #include <iostream> #include <stdio.h ...
-
基于visual Studio2013解决C语言竞赛题之1008整除数
题目 解决代码及点评 /************************************************************************/ ...
-
14.并发与异步 - 3.C#5.0的异步函数 -《果壳中的c#》
14.5.2 编写异步函数 private static readonly Stopwatch Watch = new Stopwatch(); static void Main(string[] a ...
-
Apache-Flink深度解析-DataStream-Connectors之Kafka
Kafka 简介 Apache Kafka是一个分布式发布-订阅消息传递系统. 它最初由LinkedIn公司开发,LinkedIn于2010年贡献给了Apache基金会并成为*开源项目.Kafka用 ...
-
一个python脚本解决安装mq的依赖问题
import tarfile import sys,os from _utils.patrol2 import run_cmd import zipfile def get_version(filen ...
-
date format 参数表
format 必需.规定输出日期字符串的格式.可使用下列字符: d - 一个月中的第几天(从 01 到 31) D - 星期几的文本表示(用三个字母表示) j - 一个月中的第几天,不带前导零(1 到 ...
-
JS学习-基础运动
多物体运动 多个物体用同一个函数时,函数里定义的定时器应该要每个物体对应一个定时器名称,不然会导致未完成运动就被关闭了,因为定时器名称一样,而开启定时器前会清除一下. obj.timer 多值同时运动 ...