在此记载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总结的更多相关文章

  1. Java_动态重新加载Class机制

    Java动态重新加载Class 项目中使用到了动态重新加载Class的机制,作用是让一些代码上线之前可以在线上环境测试一下,当然,这是非常不好的测试机制,我刚来的时候也为这种机制感到惊讶—怎么可以在线 ...

  2. Android系统下的动态Dex加载

    1 问题在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把使用 ...

  3. Android系统下的动态Dex加载与app速度优化

    1 问题 在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把 ...

  4. linux动态库加载RPATH, RUNPATH

    摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...

  5. 使用javassist运行时动态重新加载java类及其他替换选择

    在不少的情况下,我们需要对生产中的系统进行问题排查,但是又不能重启应用,java应用不同于数据库的存储过程,至少到目前为止,还不能原生的支持随时进行编译替换,从这种角度来说,数据库比java的动态性要 ...

  6. esri-leaflet入门教程(5)- 动态要素加载

    esri-leaflet入门教程(5)- 动态要素加载 by 李远祥 在上一章节中已经说明了esr-leaflet是如何加载ArcGIS Server提供的各种服务,这些都是服务本身来决定的,API脚 ...

  7. 【微信小程序】模仿58同城页面制作以及动态数据加载

    完成动态数据的加载,如下 使用上班的空余时间慢慢的学习,相信总有一天我会很熟悉的掌握这门技术. 本次学习小总结: 微信小程序使用的代码基本与HTML.CSS.JS等前段有关知识一样. 微信小程序js使 ...

  8. libdl.so 动态库加载、查找

    使用libdl.so库 动态库加载原理   动态库中函数的查找已经封装成 libdl.so,有4个函数: dlopen  : 打开一个动态库 dlsym   : 在打开的动态库里找一个函数 dlclo ...

  9. Vue 动态图片加载路径问题和解决方法

    最近在做一个树形结构的组件,使用了Vue和element UI中el-tree组件.因为树中每个节点都需要显示一个图标图片,并且需要根据后台传入的数据类型动态地显示,所以图片的路径需要动态地加载.下面 ...

随机推荐

  1. 2、HTML 基础知识

    一.HTT(PHyper Text Markup Language)即超文本语言. 特点: 1.通过标签来定义的语言,代码都是由标签所组成 2.不区分大小写 3.由<html>开始< ...

  2. oracle分区表知识

    在F5中查看执行计划的时候总是看到很多信息: range分区 执行计划中出现的: 分区表,按 n1 ,n2 分区 partition range single:访问单个分区 partition ran ...

  3. 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项

    我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...

  4. wdcp安装memcached解决办法

    1.下载libevent-1.4.14b-stable.tar.gz和memcached-1.4.15.tar.gz这两个文件,上传到服务器,并给它一个可用的下载地址, 如http://地址/memc ...

  5. C和指针 第五章 逻辑位移与算术位移

    对于操作数的左位移都是相同的,右边空出来的位置用0补齐. 但是对于右位移,对于有符号和无符号数是不一样的,最高位的1有两种处理方式.逻辑位移和算术位移. 逻辑位移:右移入位用0补齐 算术位移:右移入位 ...

  6. ssh框架整合-NoClassDefFoundError-NoSuchMethodError-遁地龙卷风

    (-1)写在前面 spring2.0.struts1.2.hibernate3.0.myeclipse8.5.tomcat6.0,整合之中出现了很多问题,前几天忙着整理毕业论文的资料,时间腾出来了,总 ...

  7. Servlet 之 ServletContext

    package cn.jiemoxiaodi.servlet_servletcontext; import java.io.IOException; import java.io.PrintWrite ...

  8. Hibernate POJO在序列化(JSON)时遇到的若干问题

    假设某 POJO 有属性如下: private Set<User> users = new HashSet<>(0); @OneToMany(fetch = FetchType ...

  9. js计算散点图方程式

    //pointArrayX,pointArrayY 为两个数组,分别为x轴对应的点和y轴对应的点 function getEquationPara(pointArrayX, pointArrayY) ...

  10. iOS开发UI篇—核心动画(UIView封装动画)

    iOS开发UI篇—核心动画(UIView封装动画) 一.UIView动画(首尾) 1.简单说明 UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画 ...