ClassLoader热加载的简单实现
当我们在eclipse中修改了一个.java文件时,并通过【ctrl + s 】保存了此java文件,相应的bin目录中,会发现.class文件也发生了修改。通常情况下,java文件是在我们的web项目已经启动了的情况下进行修改的,而.class文件早已加载至虚拟机中。因 此,在没有使用热部署插件的情况下,必须重启tomcat服务。而热部署插件其原理就是将修改后的.class文件重新加载至jvm中的。
public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassLoader classLoader = Test.class.getClassLoader();
Class<?> clazz = classLoader.loadClass("com.classloader.Test");
Test test = (com.classloader.Test) clazz.newInstance();
test.logic();
} public void logic() {
System.out.println("hello classloader");
}
}
1.自定义一个MyClassLoader 类
public class MyClassLoader extends ClassLoader { private static final String CLASS_PATH = System.getProperty("java.class.path"); // 编译生成的.class文件的bin目录 public MyClassLoader() {
super(ClassLoader.getSystemClassLoader());
} @Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
byte[] b = loadClassFile(className);
return super.defineClass(className, b, 0, b.length);
} private byte[] loadClassFile(String className) {
File file = new File(CLASS_PATH + "/" + className + ".class");
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b = 0;
while ( (b=fis.read())!=-1 ) {
baos.write(b);
}
fis.close();
return baos.toByteArray();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
} }
2.创建一个工厂类
public class ObjectFactory { private static final String CLASS_PATH = System.getProperty("java.class.path"); // 编译生成的.class文件的bin目录
private static Map<String, Object> map = new HashMap<String, Object>();
private static long lastModified; // 最后修改时间 private ObjectFactory() {
super();
} public static Object getInstance(String className) {
File loadFile = new File(CLASS_PATH + "/" + className.replace(".", "/") + ".class"); // 打开项目中bin目录下的*.class文件
long newModified = loadFile.lastModified();
// 文件第一次加载,通过反射的方式创建一个对象
if (map.get(className)==null) {
loadClass(className);
}
// .class 文件被修改过,通过ClassLoader方式 创建一个对象
if (lastModified!=newModified) {
loadClass(className);
}
lastModified = newModified;
return map.get(className);
} private static void loadClass(String className) {
MyClassLoader myClassLoader = new MyClassLoader();
try {
Class<?> clazz = myClassLoader.findClass(className);
Object object = clazz.newInstance();
map.put(className, object);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
3.定义一个接口,供方法调用【注:这里必须要定义一个接口类,否则会抛出类型转换错误】
public interface PrintService { public void print();
}
4.接口的实现类
public class PrintServiceImpl implements PrintService { @Override
public void print() {
System.out.println("测试一下 bbb 1111111111");
}
}
5.编写一个用于观察的线程类
public class PrintThread implements Runnable { @Override
public void run() {
String className = PrintServiceImpl.class.getName();
// 一直不断地向控制台输出信息,方便测试“当修改print 中的方法时” 输出信息是否发生变化
while (true) {
PrintService printService = (PrintService) ObjectFactory.getInstance(className);
printService.print(); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
public class Test { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Thread thread = new Thread(new PrintThread());
thread.start();
}
}
ClassLoader热加载的简单实现的更多相关文章
- 原来热加载如此简单,手动写一个 Java 热加载吧
1. 什么是热加载 热加载是指可以在不重启服务的情况下让更改的代码生效,热加载可以显著的提升开发以及调试的效率,它是基于 Java 的类加载器实现的,但是由于热加载的不安全性,一般不会用于正式的生产环 ...
- 最简破解-java代码热加载热部署IDEA插件JRebel
如果经济实力允许的话,还是建议大家去购买收费版.支持原创作者,才能有更好的产品出现. 一.Jrebel插件介绍 JRebel一款帮助我们在开发过程中实现热加载的插件,目前来说,在IDEA中实现热加载最 ...
- 最简单的操作 jetty IDEA 【debug】热加载
[博客园cnblogs笔者m-yb原创,转载请加本文博客链接,笔者github: https://github.com/mayangbo666,公众号aandb7,QQ群927113708] http ...
- SpringBoot入门笔记(三)、热加载
1.配置热加载环境,在pom.xml添加如下代码 <build> <!--springloader plugin --> <plugins> <plugin& ...
- android热加载随记
在我们日常的开发过程中,程序难免会出现BUG,一般有集中处理方式,发布新版本APP让用户来升级,或者打补丁来修复bug 前者本文在这里不错讨论,打补丁升级又分为两种一种是需要重启应用,一种是不需要.不 ...
- dubbo的jmeter压测时jar包的热加载/动态加载
在做dubbo的jmeter压测时,需要把jar包放入jmeter的lib/ext目录下,但是jmeter启动的时候会自动加载这个目录lib目录及lib/ext目录,这样启动后放入这些目录下的jar包 ...
- webpack 教程 那些事儿03-webpack两大精华插件,热加载
本节主要讲述 webpack的两大经典开发调试插件,热插拔内存缓存机制 文章目录 1. html-webpack-plugin插件的使用 2. webpack-dev-middleware 插件登场 ...
- [Eclipse] - 集成JBoss7热加载和自动发布
使用Eclipse + JBoss开发时,总是要重启项目或JBoss,烦人.下面方法可以很简单的实现Eclipse + JBoss热加载和自动发布. 我的环境是JBoss 7.1.1 Final 1) ...
- nginx多进程模型之配置热加载---转
http://blog.csdn.net/brainkick/article/details/7176405 前言: 服务器程序通常都会通过相应的配置文件来控制服务器的工作.很多情况下,配置文件会经常 ...
随机推荐
- 解决org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
这个问题来的有点莫名奇妙,之前我的hadoop运行一直是正常的,某一天开始运行Mapreduce就报这个错. 试过很多种方法都没有用,比如 1.path环境变量2.Hadoop bin目录下hadoo ...
- Java 正则表达式 Pattern & Matcher
通常会有这种需求: 在文档中搜索有规律的字符串,然后进行统计或者替换.Java.util.regex包下的Pattern和Matcher这两个类提供了通过正则表达式来匹配查询,甚至替换的功能.那么我们 ...
- Permutations,全排列
问题描述:给定一个数组,数字中数字不重复,求所有全排列. 算法分析:可以用交换递归法,也可以用插入法. 递归法:例如,123,先把1和1交换,然后递归全排列2和3,然后再把1和1换回来.1和2交换,全 ...
- scala学习手记8 - 自适应的默认做法
scala有一些默认做法,会让代码更简洁.更易读写,下面列出了这样几个特性: 1. 支持脚本.scala支持脚本,因此无须将所有的代码都放到类里.如果脚本可以满足需求,就将代码放到一个脚本里,无须再创 ...
- 如何让Myeclipse已经关闭掉的项目不显示出来
一.打开Package Explorer视图,在它的右上角有一个向下的三角图标. 2.点击后选择Filters,在弹出的Filter配置窗口中选中"Closed Projects" ...
- .Net Core使用jexus配置https
今天搞了一下怎么从http换成https,写一篇博客记录该过程.关于jexus的安装和使用请看我之前的一篇博客<Jexus部署Asp.Net Core项目>,唯一的不同是,将jexus升级 ...
- MYSQL变量和状态
mysql设置变量是在my.cnf文件里,修改配置文件后需要重启mysql的服务,才能生效.但是在线上服务器是不允许随便重启的,我们可以用命令直接修改变量值,使其生效.然后再修改配置文件中的值,以防止 ...
- c#如何保存richtextbox的rtf格式
C# codethis.rtbText.Rtf = @"{\rtf1\ansi\ansicpg936\deff0\deflang1033\deflangfe2052" + @&qu ...
- Visual Studio Nuget还原步骤
vs2013是在这里还原: NuGet套件还原步骤(以vs2012为例) 下载别人的范例,出现由于Nuget套件不存在而无法启动时:效果如下图: 步骤如下:1.点击 项目->启用NuGet程序包 ...
- MySQL 福利彩票业务 如何存储毫秒微秒
朋友在做福利彩票业务,遇到一个存储毫秒微秒数据的需求,问我mysql里面有何解决方案.我脑中一搜索,以前没有关注到,于是去官网查看,找到11.3.6 Fractional Seconds in Tim ...