实现类的热部署

即使是同个ClassLoader类的两个是实例,加载同个类也会不一样。所以实现类的热部署可以创建不同ClassLoader的实例对象,通过这两个不同的实例对象加载同名的类。发现xx.class文件被修改就执行加载。

package dou_dir_list;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ClassReloader extends ClassLoader {
    private String classPath;
    String classname = "dou_dir_list.ListTest";
    public ClassReloader(String classPath){
        this.classPath = classPath;
    }
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classData = getData(name);
        if(classData == null){
            throw new ClassNotFoundException();
        }else{
            return defineClass(classname, classData, 0, classData.length);
        }
    }
    private byte[] getData(String className) {
        String path = classPath + className;
        try {
            InputStream is = new FileInputStream(path);
            ByteArrayOutputStream stream  = new ByteArrayOutputStream();
            byte[] buffer = new byte[2048];
            int num = 0;
            while((num = is.read(buffer)) != -1){
                stream.write(buffer,0,num);
            }
            return stream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static void main(String[] args) {
        /**
         * 同路径同名的某xx.class文件由两个不同的ClassLoader实例对象分别加载后再实例出的对象是两个不同的实例
         */
        try {
            String path = "E:/develop_workspaces/ssm/my_linked_list/bin/dou_dir_list/";
            
            ClassReloader reloader = new ClassReloader(path);
            Class r = reloader.findClass("ListTest.class");
            System.out.println(r.newInstance());
            
            ClassReloader reloader2 = new ClassReloader(path);
            Class r2 = reloader2.findClass("ListTest.class");
            System.out.println(r2.newInstance());
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
原理是这样,这种方式可以为在开发时修改类频繁重启节省些时间。但是原来已经被引用的对象就不好让JVM去栈中替换了,这违反JVM的设计原则。还有点问题是加载的类会进入PermGen,在Full GC时才回收,所以改动频繁时间长了可能会有溢出问题,所以也就开发时用用。JVM不知道运行时类型,只知道编译类型。可以像JSP一样不保存对象状态,创建使用后立即释放,再修改又是新的。

转载于:https://my.oschina.net/u/1052786/blog/1816727

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值