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. VS 2017 VC++项目出现 LNK1104 无法打开文件"libcmtd.lib" 的解决方法

    今天用VS 2017编译一个以前的VC++动态库项目,出现了一个链接器问题: LNK1104 无法打开文件"libcmtd.lib" . 操作系统版本为:Windows 10 18 ...

  2. 在Tomcat中配置MySQL数据源

    打开context.xml文件,路劲为:apache-tomcat-7.0.61\conf,添加如下代码: <Resource auth="Container" driver ...

  3. 【flask】表单-上传文件

    依赖: flask-wtf upload_case.html <!DOCTYPE html> <html lang="en"> <head> & ...

  4. ping命令介绍

    1.ping是TCP/IP协议的一部分,所以只要安装了TCP/IP协议就(无论windows或linux)都可以使用ping命令. 2.ping命令的原理:本机创建一个数据包发送给(ping对象)目标 ...

  5. 【ZT】Enhancement Framework – Introduction

    Enhancement Framework – Introduction By Naimesh Patel | March 26, 2014 | Enhancement Implementation ...

  6. MySQL MGR 5.7.22 on centos 6.3 单主/多主搭建测试

    搭建Mysql Group Replication本次搭建采用3个实例,三个服务器,同一个网段,MGR的参数配置在配置文件中添加.注意通讯端口号的配置,它用于组成员之间的通讯使用请确定当前MySQL版 ...

  7. ElasticSearch的中文分词器ik

    一.前言   为什么要在elasticsearch中要使用ik这样的中文分词呢,那是因为es提供的分词是英文分词,对于中文的分词就做的非常不好了,因此我们需要一个中文分词器来用于搜索和使用. 二.IK ...

  8. unity中的常遇到的问题

    1.使用unity的MovieTexture播放视频在物体上,对象只能在电脑上 2.移动端播放全屏视频 Handheld.PlayFullScreenMovie(),视频文件必须放置在Streamin ...

  9. Windos下navcat连接虚拟机中的mysql

    进入mysql命令行, 使用root用户,密码:youpassword(你的root密码)连接到mysql服务器: # mysql -u root -proot  mysql>GRANT ALL ...

  10. [开发技巧]·pandas如何保存numpy元素

    [开发技巧]·pandas如何保存numpy元素 ​ 1.问题描述 在开发的过程中遇到一个问题,就是需要把numpy作为pandas的一个元素进行保存,注意不是作为一列元素.但是实践的过程中却不顺利, ...