自定义类加载器的使用实例

自定义的类加载器必须继承ClassLoader抽象类,并覆盖findClass方法。

测试的需要被加密使用的类:

package com.franky.classloader;

import java.util.Date;

/**
 * @描述   加密的测试类,需要用自定义的类加载器加载
 * @作者 franky
 * @日期 2015-1-1 下午9:51:38
 * 
 */
public class TestMyClass extends Date {

	@Override
	public String toString() {
		return "hello,world";
		
	}
}

自定义的类加载器,能够对类进行加密解密:

package com.franky.classloader;

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

/**
 * @描述   自定义的类加载器,提供对类的加载,加密与加密
 * @作者 franky
 * @日期 2015-1-1 下午9:47:14
 * 
 */
public class MyClassLoader extends ClassLoader{

	/**
	 * 进行class文件的加密
	 * @param args 传入的源文件路径,和加密后的文件夹存储路径
	 * @throws IOException 抛出的IO异常
	 */
	public static void main(String[] args) throws IOException {
		FileInputStream ips = new FileInputStream(args[0]);
		String destFile = args[0].substring(args[0].lastIndexOf("\\")+1);
//		System.out.println(destFile);
//		System.out.println(args[1]);
		if(!(new File(args[1])).exists()){
			new File(args[1]).mkdir();
		}
		String destPath = args[1]+"\\"+destFile;
		FileOutputStream ops = new FileOutputStream(destPath);
		encrypt(ips,ops);
		ips.close();
		ops.close();
	}

	/**
	 * 类的加密器与解密器
	 * @param ips 需要加密的class文件读取流
	 * @param ops 加密完成的class文件输出流
	 * @throws IOException 抛出的IO异常
	 */
	private static void encrypt(InputStream ips, OutputStream ops) throws IOException {
		int b = -1;
		while((b = ips.read())!=-1){
			ops.write(b^0xff);
		}
	}

	private String classDir;

	public MyClassLoader() {
		
	}

	/**类加载器的有参构造方法
	 * @param classDir 存放加密类的目录
	 */
	public MyClassLoader(String classDir) {
		this.classDir = classDir;
	}
	

	@Override
	/* 覆盖findClass方法后,才能实现自定义加载类
	 * 该方法负责从加密的class目录中,加载自定义的加密类,解密后返回该类的Class对象
	 */
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		String className = name.substring(name.lastIndexOf(".")+1)+".class";
		String destPath = this.classDir +"\\"+className;
		try {
			FileInputStream fis = new FileInputStream(destPath);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			encrypt(fis,bos);
			byte[] bs = bos.toByteArray();
			Class<?> defineClass = defineClass(null,bs, 0, bs.length);
			return defineClass;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.findClass(name);
	}
	

}
测试自定义类加载器的测试主类:

package com.franky.classloader;

import java.util.Date;

/**
 * @描述    测试自定义的类加载器
 * @作者 franky
 * @日期 2015-1-1 下午10:11:05
 * 
 */
public class MyClassLoaderTest {

	public static void main(String[] args) throws Exception {
		//经过加密的类加载器对TestMyclass.class文件加载,该实例对象的.class文件是无法正常加载的
		//System.out.println(new TestMyClass());
		//用自定义的类加载器对TestMyclass.class进行加载,按照原始路径加载,classpath下找不到,
		//然后返回自定义的类加载器,执行findClass方法,找到对应的加密类.class文件进行加载
		Class<?> clazz = new MyClassLoader("mylib").loadClass("com.franky.classloader.TestMyClass");
		//不能直接转换为被加密的类,因为字节码已经被加密了,所以只能向上转型加载它的父类型
		Date obj = (Date) clazz.newInstance();
		//能够正确输出
		System.out.println(obj);
		
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值