Java_动态重新加载Class总结
在此记载Java动态重新加载Class的点点滴滴,实现之前也在网上看了很多文章,但发现不是很清晰,后来发现总结,看源码实现还是最靠谱。
直接上代码:
package com.lkb.autoCode.util; import com.lkb.autoCode.constant.AutoCodeConstant; import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream; /**
* DynamicClassLoader 动态类加载器
*
* @author Lilin
* @date 2016/5/23
*/
public class DynamicClassLoader extends ClassLoader { private String classPath; public DynamicClassLoader(String classPath, ClassLoader parent) {
super(parent);
this.classPath = classPath;
} @Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
// 判断当前加载的类是否是需要动态重新加载的类,
// 假如是通过重写的findClass在自定义的ClassLoader里面加载,
// 假如不是就调用父ClassLoader默认加载
if (name != null && name.equals(classPath)) {
return findClass(name);
}
return super.loadClass(name, false);
} /**
* 根据类名查找class
*
* @param fullClassPath 类全路径(包)
* @return
* @throws ClassNotFoundException
*/
@Override
protected Class<?> findClass(String fullClassPath)
throws ClassNotFoundException {
byte[] raw = readClassBytes(fullClassPath);
// definClass方法参数说明:name:类包的全路径如com.lkb.sb.client.shanghaiC.ShangHaiLoginClient
// b:读取的class文件的byte数组
// off:从byte数组中读取的索引
// len:从byte数组中读取的长度
// 注:假如此类中有引入别的class类,如com.lkb.sb.client.BaseClient,循环执行findClass方法
Class<?> clazz = defineClass(fullClassPath, raw, 0, raw.length);
// 连接class
resolveClass(clazz);
return clazz;
} /**
* 读取class
*
* @param fullClassPath
* @return
*/
private byte[] readClassBytes(String fullClassPath) {
byte[] raw = null;
InputStream stream = null;
try {
File file = new File(AutoCodeConstant.BASE_PATH + fullClassPath.replaceAll("\\.", "/") + AutoCodeConstant.CLASS_SUFFIX);
stream = new FileInputStream(file);
raw = new byte[(int) file.length()];
stream.read(raw);
} catch (Exception e) { } finally {
try {
stream.close();
} catch (Exception e) {
}
}
return raw;
} }
注:调用方式:
// 通过自定义类加载器来加载
// 获取类的完成路径
String fullClassPath = getFullClassPath(AutoCodeConstant.CLIENT_PACKAGE, provinceCode, cityCode, AutoCodeConstant.LOGIN_CLIENT);
// 父ClassLoader设为当前线程的ClassLoader,试过使用ClassLoader.getSystemClassLoader(),发现获取的是系统级的,懒加载的类找不到
dynamicClassLoader = new DynamicClassLoader(fullClassPath, Thread.currentThread().getContextClassLoader());
loginInterface = (LoginInterface) dynamicClassLoader.loadClass(fullClassPath).getConstructor(new Class[]{CommonLoginSb.class, SbDefultModel.class}).newInstance(new Object[]{commonLoginSb, sbDefultModel});
// 执行start方法
resOutput = loginInterface.start(commonLoginSb.getMethod());
Java_动态重新加载Class总结的更多相关文章
- Java_动态重新加载Class机制
Java动态重新加载Class 项目中使用到了动态重新加载Class的机制,作用是让一些代码上线之前可以在线上环境测试一下,当然,这是非常不好的测试机制,我刚来的时候也为这种机制感到惊讶—怎么可以在线 ...
- Android系统下的动态Dex加载
1 问题在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把使用 ...
- Android系统下的动态Dex加载与app速度优化
1 问题 在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把 ...
- linux动态库加载RPATH, RUNPATH
摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...
- 使用javassist运行时动态重新加载java类及其他替换选择
在不少的情况下,我们需要对生产中的系统进行问题排查,但是又不能重启应用,java应用不同于数据库的存储过程,至少到目前为止,还不能原生的支持随时进行编译替换,从这种角度来说,数据库比java的动态性要 ...
- esri-leaflet入门教程(5)- 动态要素加载
esri-leaflet入门教程(5)- 动态要素加载 by 李远祥 在上一章节中已经说明了esr-leaflet是如何加载ArcGIS Server提供的各种服务,这些都是服务本身来决定的,API脚 ...
- 【微信小程序】模仿58同城页面制作以及动态数据加载
完成动态数据的加载,如下 使用上班的空余时间慢慢的学习,相信总有一天我会很熟悉的掌握这门技术. 本次学习小总结: 微信小程序使用的代码基本与HTML.CSS.JS等前段有关知识一样. 微信小程序js使 ...
- libdl.so 动态库加载、查找
使用libdl.so库 动态库加载原理 动态库中函数的查找已经封装成 libdl.so,有4个函数: dlopen : 打开一个动态库 dlsym : 在打开的动态库里找一个函数 dlclo ...
- Vue 动态图片加载路径问题和解决方法
最近在做一个树形结构的组件,使用了Vue和element UI中el-tree组件.因为树中每个节点都需要显示一个图标图片,并且需要根据后台传入的数据类型动态地显示,所以图片的路径需要动态地加载.下面 ...
随机推荐
- Raid与DAN、SAN、NAS基础
一. 磁盘基本知识 1. Raid分类 Raid磁盘阵列是由多个磁盘组合成的磁盘组,可将数据分割成许多区段,分别存放在各个磁盘上:同时利用不同排列技术,可提高磁盘性能和数据安全性.下列简单介绍几种Ra ...
- Android高手速成--第一部分 个性化控件(View)
第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Pro ...
- 多种JSON格式及遍历方式
/*数组*/ var arr = [["name", "value"], ["name1", "value1"]]; v ...
- PYTHON 写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者
def a2(arg): if len(arg) > 2: del arg[2:] li = [12,13,14,15] a2(li) print(li)
- 上个项目的一些反思 I
最近一直在反思之前的项目,发现了很多问题.比如数据安全... 虽然项目需求是只展示最新的数据,所以几乎没用什么本地存储.除了通讯录和用户的Token. 用户通讯录另表,今天反思下用户的Token的存储 ...
- JQuery Mobile 页面参数传递
在单页模版中使用基于HTTP的方式通过POST和GET请求传递参数,而在多页模版中不需要与服务器进行通信,通常在多页模版中有以下三种方法来实现页面间的参数传递. 1.GET方式:在前一个页面生成参数并 ...
- javascript删除数组某个元素
1.首先可以给js的数组对象定义一个函数,用于查找指定的元素在数组中的位置,即索引 Array.prototype.indexOf = function(val) { for (var i = 0; ...
- C#转义字符(Z)
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示.而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为 ...
- Class.forName的使用
Class.forName的使用 Class.forName返回一个类,使用此方法可以获取类 首先,创建一个Student类 /*** * This Class is for Student bean ...
- qt 标准对话框
if (QMessageBox::Yes == QMessageBox::question(this, tr("Question"), ...