1. 程式人生 > >自定義 java 加載器

自定義 java 加載器

new dmi ESS class a length turn ngs 加密 list

先寫個java類的:
allen.java

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

/**
 * 加載類
 * @author Administrator
 */
public class allen extends Date{
   // private static final long serialVersionUID = 8627644427315706176L;
    //打印數據
    @Override
    public String toString(){
        return "Hello ClassLoader!";
    }
    public static void main(String[] args){
        System.out.println("List類的加載器的名稱:"+List.class.getClassLoader());
    }

}

運行:
技術分享圖片
然後把編譯的.class文件放到 其它 目錄下
技術分享圖片
新建一個class_temp用於保存加密的class文件
防止沖突修改下名字
技術分享圖片
編寫自定義加載器:
//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);
        }
    }

}

添加倆個參數 也可以直接寫死
技術分享圖片
先運行自定義的加載器(因為有 main 函數 用於加密)
運行完後就多了個加密後的類
技術分享圖片
技術分享圖片
編寫測試類
//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!

運行
技術分享圖片
發現 main 沒運行 這是很定的!!!!
結論是可以自行加載加密的 class 文件

自定義 java 加載器