【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件

1、要想实现自己的类加载器能够加载类,需要覆盖findClass(String name)方法,类加载器的loadClass(String name)方法最终调用的还是findClass(String name)。

2、由于类加载器使用的委托机制,先看父类AppClassLoader能不能加载再看自己的类加载器能不能加载,所以要把bin目录下的class文件删掉。

下面是自己写的类加载器,具有加密功能

package com.xiaozhi.myclassloader;

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

public class MyClassLoader extends ClassLoader{
	
	public static void main(String[] args) throws Exception{//生成加密字节码文件
		String srcPath = args[0];
		String destPah = args[1];
		String fileName = srcPath.substring(srcPath.lastIndexOf("\\") + 1);
		destPah = destPah +"\\"+fileName;

		FileInputStream fileInputStream = new FileInputStream(srcPath);
		FileOutputStream fileOutputStream = new FileOutputStream(destPah);
		encrypt(fileInputStream, fileOutputStream);
		fileInputStream.close();
		fileOutputStream.close();
	}
	
	private String classDir;
	
	public MyClassLoader(){
		
	}
	public MyClassLoader(String classDir){
		this.classDir=classDir;
	}
	
	@Override
	protected Class findClass(String name) throws ClassNotFoundException {
		String classFileName =classDir+"\\"+name.substring(name.lastIndexOf('.')+1)+".class";
		try {
			FileInputStream fileInputStream = new FileInputStream(classFileName);
			ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
			encrypt(fileInputStream, arrayOutputStream);
			fileInputStream.close();
			byte[] bytes = arrayOutputStream.toByteArray();
			return defineClass(bytes, 0, bytes.length);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.findClass(name);
	}

	public static void encrypt(InputStream inputStream,OutputStream outputStream) throws Exception
	{
		int b = 0;
		while((b=inputStream.read())!=-1)
		{
			outputStream.write(b^0xff);
			outputStream.flush();
		}
	}
}
类加载器需要加载的类,继承于Date,

package com.xiaozhi.myclassloader;

import java.util.Date;

public class ClassLoaderAttachment extends Date{
	@Override
	public String toString() {
		return "hello heima";
	}
}
测试类

package com.xiaozhi.testmyclassloader;

import java.util.Date;

import com.xiaozhi.myclassloader.MyClassLoader;



public class Test {

	public static void main(String[] args) throws Exception{
		Class clazz=new MyClassLoader("mylib").loadClass("com.xiaozhi.myclassloader.ClassLoaderAttachment");
//		ClassLoaderAttachment loaderAttachment= (ClassLoaderAttachment) clazz.newInstance();//这里不能这样写,因为class文件已经删除,编译器找不到Class文件。
		Date date=(Date) clazz.newInstance();
		System.out.println(date);
		
	}
}

运行结果

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第1张图片

把加密的class复制到原class目录下

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第2张图片

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第3张图片

运行程序:

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第4张图片

找到需要类加载器需要加载的类,敲一个回车,保存一下,生成新的class文件

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第5张图片

再次运行

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第6张图片

再次把这个新生出的class文件删了

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第7张图片

再次运行

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件_第8张图片


你可能感兴趣的:(类加载器)