自定义 java 加载器

先写个java类的:
allen.java

import java.util.Date;
/**
 * 加载类
 * @author Administrator
 */
public class allen extends Date{
    private static final long serialVersionUID = 8627644427315706176L;
    //打印数据
    @Override
    public String toString(){
        return "Hello ClassLoader!";
    }

}

然后把编译的.class文件放到 其它 目录下
自定义 java 加载器
新建一个class_temp用于保存加密的class文件
防止冲突修改下名字
自定义 java 加载器
编写自定义加载器:
//MyClassLoader.java

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 自定义的类加载器
 * @author Administrator
 */
public class MyClassLoader extends ClassLoader{

    //需要加载类.class文件的目录
    private String classDir;

    //无参的构造方法,用于class.newInstance()构造对象使用
    public MyClassLoader(){
    }

    public MyClassLoader(String classDir){
        this.classDir = classDir;
    }

    @SuppressWarnings("deprecation")
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //class文件的路径
        String classPathFile = classDir + "/" + name + ".class";
        try {
            //将class文件进行解密
            FileInputStream fis = new FileInputStream(classPathFile);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            encodeAndDecode(fis,bos);
            byte[] classByte = bos.toByteArray();
            //将字节流变成一个class
            return defineClass(classByte,0,classByte.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return super.findClass(name);
    }

    //测试,先将ClassLoaderAttachment.class文件加密写到工程的class_temp目录下
    public static void main(String[] args) throws Exception{
        //配置运行参数
        //String srcPath = args[0];//ClassLoaderAttachment.class原路径
        String srcPath = "/Users/liuhailong/IdeaProjects/testjava/allen.class";
        //String desPath = args[1];//ClassLoaderAttachment.class输出的路径
        String desPath ="/Users/liuhailong/IdeaProjects/testjava/class_temp";
        String desFileName = srcPath.substring(srcPath.lastIndexOf("/")+1);
        String desPathFile = desPath + "/" + desFileName;
        FileInputStream fis = new FileInputStream(srcPath);
        FileOutputStream fos = new FileOutputStream(desPathFile);
        //将class进行加密
        encodeAndDecode(fis,fos);
        fis.close();
        fos.close();
    }

    /**
     * 加密和解密算法
     * @param is
     * @param os
     * @throws Exception
     */
    private static void encodeAndDecode(InputStream is,OutputStream os) throws Exception{
        int bytes = -1;
        while((bytes = is.read())!= -1){
            bytes = bytes ^ 0xff;//和0xff进行异或处理
            os.write(bytes);
        }
    }

}

添加俩个参数 也可以直接写死
自定义 java 加载器
先运行自定义的加载器(因为有 main 函数 用于加密)
运行完后就多了个加密后的类
自定义 java 加载器
自定义 java 加载器
编写测试类
//ClassLoaderTest.java

import java.util.Date;
import java.util.List;

/**
 * 测试类
 * @author Administrator
 */
public class ClassLoaderTest {

    @SuppressWarnings("rawtypes")
    public static void main(String[] args){
        //输出ClassLoaderText的类加载器名称
        System.out.println("ClassLoaderText类的加载器的名称:"+ClassLoaderTest.class.getClassLoader().getClass().getName());
        System.out.println("System类的加载器的名称:"+System.class.getClassLoader());
        System.out.println("List类的加载器的名称:"+List.class.getClassLoader());

        System.out.println("默认的类加载器:"+ClassLoaderTest.class.getClassLoader().getSystemClassLoader());

        ClassLoader cl = ClassLoaderTest.class.getClassLoader();
        while(cl != null){
            System.out.print(cl.getClass().getName()+"->");
            cl = cl.getParent();
        }
        System.out.println(cl);

        try {
            Class classDate = new MyClassLoader("/Users/liuhailong/IdeaProjects/testjava/class_temp").loadClass("allen");
            Date date = (Date) classDate.newInstance();
            //输出ClassLoaderAttachment类的加载器名称
            System.out.println("ClassLoader:"+date.getClass().getClassLoader().getClass().getName());
            System.out.println(date);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

}
ClassLoaderText类的加载器的名称:sun.misc.Launcher$AppClassLoader
System类的加载器的名称:null
List类的加载器的名称:null
默认的类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader->sun.misc.Launcher$ExtClassLoader->null
ClassLoader:MyClassLoader
Hello ClassLoader!

运行
自定义 java 加载器

猜你喜欢

转载自blog.51cto.com/haidragon/2175702