日志文章

2020-1-3 aflfte2011

自定义类加载器

package com.aflfte.test;
/**
 * 测试自定义的fileSystemClassLoader
 *
 *
 * @author root
 *
 */
public class Demo03 {
    public static void main(String[] args) throws Exception {
        FileSystemClassLoader loader=new FileSystemClassLoader("/root/myjava");
        FileSystemClassLoader l2=new FileSystemClassLoader("/root/myjava");
        Class<?> c=loader.loadClass("com.aflfte.test.HelloWorld");
        Class<?> c2=loader.loadClass("com.aflfte.test.HelloWorld");
        Class<?> c3=l2.loadClass("com.aflfte.test.HelloWorld");
        Class<?> c4=l2.loadClass("java.lang.String");
        Class<?> c5=l2.loadClass("com.aflfte.test.Demo03");
        System.out.println(c.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());//同个类被不同的加载器加载JVM也会认为它是不同的两个类
        System.out.println(c4.hashCode());
        System.out.println(c4.getClassLoader());//c4使用的是引导类加载器
        System.out.println(c3.getClassLoader());//c3使用的是自定义的类加载器
        System.out.println(c5.getClassLoader());//c5为系统默认的类加载器进行加载的
    }
}

自定义文件系统类加载器
package com.aflfte.test;

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

/**
 * 自定义文件系统类加载器
 * @author root
 *
 */
//第一步继承ClassLoader
public class FileSystemClassLoader extends ClassLoader {
    //转化过程:com.aflfte.test.User-->/root/mywork/类加载全过程/src/com/aflfte/test/User.class
    private String rootDir;

    public FileSystemClassLoader(String rootDir) {
        super();
        this.rootDir = rootDir;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> c=findLoadedClass(name);
        if(c!=null) {//先检查有没有加载这个类,如果已经加载,则直接返回加载好的类.如果没有则加载新的类
            
            return c;
        }else {//如果没有加载则要他的父类先加载
            ClassLoader parent=this.getParent();
            try {
            c=parent.loadClass(name);//委派给父类加载器进行加载
            }catch (Exception e) {
                //e.printStackTrace();
            }
            if(c!=null) {
                return c;
            }else {
                byte[] classData=getClassData(name);
                if(classData==null) {
                    throw new ClassNotFoundException();//如果没有加载成功则抛出异常
                }else {
                    c=defineClass(name, classData, 0, classData.length);
                }
            }
        }
        return c;
    }
    private byte[] getClassData(String classname) {
        String path=rootDir+"/"+classname.replace(".", "/")+".class";
        //IOUtils可以使用它装数据流中的数据转成数组
        InputStream is=null;
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        try {
            is=new FileInputStream(path);
            byte[] buffer=new byte[1024];
            int temp=0;
            while((temp=is.read(buffer))!=-1) {
                baos.write(buffer, 0, temp);
            }
            baos.flush();
            return baos.toByteArray();
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
            return null;
        }finally {
            try {
                if(is!=null) {
                    is.close();
                }
                if(baos!=null) {
                    baos.close();
                }
                    
                } catch (IOException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
            }
        
        //return null;
    }
    
}



网络类加载器
package com.aflfte.test;

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

/**
 * 网络类加载器
 * @author root
 *
 */
//第一步继承ClassLoader
public class NetSystemClassLoader2 extends ClassLoader {
    //转化过程:com.aflfte.test.User-->/root/mywork/类加载全过程/src/com/aflfte/test/User.class
    private String rootUrl;

    public NetSystemClassLoader2(String rootUrl) {
        super();
        this.rootUrl = rootUrl;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> c=findLoadedClass(name);
        if(c!=null) {//先检查有没有加载这个类,如果已经加载,则直接返回加载好的类.如果没有则加载新的类
            
            return c;
        }else {//如果没有加载则要他的父类先加载
            ClassLoader parent=this.getParent();
            try {
            c=parent.loadClass(name);//委派给父类加载器进行加载
            }catch (Exception e) {
                //e.printStackTrace();
            }
            if(c!=null) {
                return c;
            }else {
                byte[] classData=getClassData(name);
                if(classData==null) {
                    throw new ClassNotFoundException();//如果没有加载成功则抛出异常
                }else {
                    c=defineClass(name, classData, 0, classData.length);
                }
            }
        }
        return c;
    }
    private byte[] getClassData(String classname) {
        String path=rootUrl+"/"+classname.replace(".", "/")+".class";
        //IOUtils可以使用它装数据流中的数据转成数组
        InputStream is=null;
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        try {
            URL url=new URL(path);
            is=url.openStream();
            byte[] buffer=new byte[1024];
            int temp=0;
            while((temp=is.read(buffer))!=-1) {
                baos.write(buffer, 0, temp);
            }
            baos.flush();
            return baos.toByteArray();
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
            return null;
        }finally {
            try {
                if(is!=null) {
                    is.close();
                }
                if(baos!=null) {
                    baos.close();
                }
                    
                } catch (IOException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
            }
        
        //return null;
    }
    
}


« 简单的加密和解密类文件加载器 | javassist动态操作类的属性、方法、构造器、注解»