Copy备用

之前客户要求在不重启应用的前提下实现动态增加服务及交易,在网上查了很长时间也没发现类似的技术,最后研究了一下ClassLoader。因为项目是与Spring,一开始我和同事尝试替换源码的class文件,然后调用Spring的refresh()函数刷新上下文,但是发现原来的类没有被新的类替换。于是我看了一下ClassLoader相关的内容,发现默认的系统类加载器加载类后就不会再次加载。然后我想到要定义自己的类加载器,最后可以实现动态替换原来的类了。虽然最后没能应用在项目中,但是初步了解了一下ClassLoader原理让我感觉挺兴奋的,打算以后再做一下深入的研究,先把源码拷贝下来。

class NetClassLoader extends ClassLoader{
 private byte[] bb = null;
 //private String className = null;
 public NetClassLoader(){
  //super();
  super(ClassLoader.getSystemClassLoader().getParent());//让定义的类加载器与默认的系统类加载器平级
 }
 
 public Class<?> loadClass(String name) throws ClassNotFoundException {
  return loadClass(name, false);
 }
// public Class<?> getLoadedClass(String className)throws ClassNotFoundException{
//  Class c = null;
//  
//  FileInputStream fis;
//  try {
//   
//   fis = new FileInputStream("bin\\"+className+".class");
//   int length = 0;
//   length = fis.available();
//   bb = new byte[length];
//   fis.read(bb);
//   fis.close();
//  } catch (FileNotFoundException e) {
//   throw new ClassNotFoundException("所要加载的类的字节码文件不存在");
//  } catch (IOException e) {
//   throw new RuntimeException("加载字节码文件时出错");
//  }
//
//      c = findClass(className);
//      return c;
// }
 protected synchronized Class<?> loadClass(String className, boolean resolve)
 throws ClassNotFoundException
    {
 Class c = findLoadedClass(className);
 FileInputStream fis = null;
 if(c == null){
  try{
   c = super.loadClass(className, resolve);
  }catch(ClassNotFoundException e){
   
   try {
  
    fis = new FileInputStream("bin\\"+className+".class");
    int length = 0;
    length = fis.available();
    bb = new byte[length];
    fis.read(bb);
    fis.close();
   } catch (FileNotFoundException fe) {
    throw new ClassNotFoundException("所要加载的类的字节码文件不存在");
   } catch (IOException ie) {
    throw new RuntimeException("加载字节码文件时出错");
   }
     c = defineClass(className,bb,0,bb.length);//createClass(className);
  }
 }
 if (resolve) {
     resolveClass(c);
 }
     return c;
    }
 
// public NetClassLoader(byte[] b){
//  bb = b;
// }
 public Class createClass(String className){
  Class klass = defineClass(className,bb,0,bb.length);
  if(klass == null)
   System.out.println("是空的");
  return klass;
 }
}

使用java的自定义classloader机制实现类的动态加载。

//自定义classloader
public class StrategyClassLoader extends ClassLoader { //通过该方法实现类的加载
public Class<BaseStrategy> loadStrategyClass(String name) throws FileNotFoundException, IOException {
String classname = name.replace('.', File.separatorChar) + ".class";
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(classname);
Class<BaseStrategy> cls = instantiateClass(name, is, is.available());
return cls;
} @SuppressWarnings("unchecked")
private Class<BaseStrategy> instantiateClass(String name, InputStream fin, long len) throws IOException {
byte[] raw = new byte[(int) len];
try {
fin.read(raw);
} finally {
fin.close();
}
return (Class<BaseStrategy>) defineClass(name, raw, 0, raw.length);
} } //类加载器classloader的使用
new StrategyClassLoader().loadStrategyClass("com.xxx.xxxx.DummyStrategy");

注意:

  • 该classloader每次都重新读取class文件,实际使用时需要根据自己的需求决定是不是需要缓存。比如可以先检测class文件的时间戳是否变化再确定要不要通过new StrategyClassLoader来重新加载类,否则的话可以使用老的classloader并将之前加载过的class缓存起来以提高性能。

  • 你可以重写loadClass方法来实现目标,但这里我觉得没什么必要。

  • 是不是没更新一次类都要新建立一个classloader?是的,同个classloader中对于相同的类只能加载一次,如果想实现类的不断更新,必须建立新的classloader。

  • 建立这么多的classloader会不会导致内存或者其他资源问题?不会,classloader也只是一个普通的java对象,他一样会被GC垃圾回收掉。所以不用担心太多classloader导致资源不足问题,当然,我们尽可能的减少classloader的创建,毕竟类的加载也是挺耗时的操作。

为了实现动态加载而编写的自己的ClassLoader的更多相关文章

  1. Android 动态加载(防止逆向编译) jar混淆加密

    最近工作中接到了一个研究防止逆向编译的任务.研究了几天资料,最后基本实现了防破解技术,在这个工程中,也略有一些心得体会,现整理下来分享,供大家探讨参考研究.文中如有纰漏.失实之处,请大家及时给与指正. ...

  2. 编写软件动态加载NT式驱动

    NT式设备驱动程序的动态加载主要是由服务控制管理程序(Service Control Manager,即SCM)系统组件来完成的. Windwos服务可以在系统启动时加载,用户也可以按需在服务控制平台 ...

  3. CS.动态加载DLL.动态生成.运行代码.BS.AutoFac管理实现类

    以英雄联盟为例.界面上经常有Load....xxxx.dll.一般都是加载子系统.比如装备系统.英雄系统等.在实际开发中很多项目非常庞大.都会分割成独立子解决方案开发.后期就需要加载回来.一般都是利用 ...

  4. Dex动态加载

    Dex动态加载是为了解决什么问题? 在Android系统中,一个App的所有代码都在一个Dex文件里面. Dex是一个类似Jar的存储了多个Java编译字节码的归档文件. 因为Android系统使用D ...

  5. ligerui_ligerTree_007_ligerTree动态加载节点

    ligerui:ligerTree:动态加载节点: 源码地址:http://download.csdn.net/detail/poiuy1991719/8571255 效果图: 代码:json.txt ...

  6. Android中插件开发篇之----动态加载Activity(免安装运行程序)

    一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...

  7. Android中的动态加载机制

    在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...

  8. Android 动态加载 (一) 态加载机制 案例一

    在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...

  9. Linux中mod相关的命令 内核模块化 mod相关命令都是用来动态加载内核模块/驱动程序模块

    Linux中mod相关的命令 内核模块化   mod相关命令都是用来动态加载内核模块/驱动程序模块 http://baike.baidu.com/link?url=lxiKxFvYm-UfJIxMjz ...

随机推荐

  1. 作业要求20191010-4 alpha week 1/2 Scrum立会报告+燃尽图 02

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8747 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 杨萍队名:胜 ...

  2. 七、创建UcRESTTemplate请求管理器

    一.创建UcRESTTemplate管理器封装 import com.alibaba.fastjson.JSON; import org.apache.http.client.config.Reque ...

  3. 【剑指offer38】字符串的排列

    如果没有要求字典序排序,则直接采用递归的思想,将字符串的排列看成两步,第一步,交换第一个字母和任意一个字母(包括自己,但不包括和自己相等的其他字母)固定第一个字母,固定第一个字母,然后对后面的字符串也 ...

  4. Ubuntu13.04编译安装cmake2.8.12.2

    前提: 安装过程需要gcc和gcc-c++.ubuntu13.04桌面版自带gcc4.7,apt-get install g++4.7安装g++./usr/bin目录下有x86_64-linux-gn ...

  5. 阶段3 2.Spring_04.Spring的常用注解_1 今日课程内容介绍

  6. kernel function

    下面这张图位于第一.二象限内.我们关注红色的门,以及“北京四合院”这几个字下面的紫色的字母.我们把红色的门上的点看成是“+”数据,紫色字母上的点看成是“-”数据,它们的横.纵坐标是两个特征.显然,在这 ...

  7. Session对象的生命周期(面试题/笔试题)

    创建:第一次执行request.getSession()时创建 销毁: 1)服务器(非正常)关闭时 2)session过期/失效(默认30分钟) 问题:时间的起算点 从何时开始计算30分钟? 从不操作 ...

  8. 占位图片placehold.it生成

    (1)默认:http://www.placehold.it/350x200/cccccc/969696.jpg/&text=loading.. (2)格式:http://www.placeho ...

  9. 使用Jquery的Ajax调用

    最近在学习web开发,试用了一下Jquery的ajax调用. 首先,新建一个MVC4的项目,在HomeController.cs中添加一个Action,命名为GetData, 通过这个为ajax提供数 ...

  10. this引用逸出

    1.定义 public class UnsafeClass { public UnsafeClass(Button button) { button.addActionListener(new Act ...