自定义文件系统类加载器

自定义类加载器的流程:

继承:java.lang.ClassLoader

重写findClass方法,首先检查请求的类型是否已经被这个类装载器装载到命名空间中了,如果已经装载,直接返回,如果没有,委派类加载器请求给父类加载器,如果父类加载器能够完成,则返回父类加载器加载的class实例;如果父类加载器不能完成,试图读取该文件目录下该类.class文件,即字节码文件是否有数据,如果获取到数据,则调用defineClass方法导入类型到方法区,如果获取不到对应的字节码或者其他原因失败,返回异常给loadClass,loadClass抛出异常,终止加载过程

强调:被两个类加载器加载的同一个类,jvm不认为是相同的类。

例子:自定义文件系统类加载器,在电脑f:\myjava目录下有HelloWorld.java文件,已经编译执行


package com.test;

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

/**
 * 自定义文件系统类加载器
 * 
 * @author pomay
 *
 */
public class FileSystemClassLoader extends ClassLoader
{
	// 传一个com.pomay.test.HelloWorld -->
	// f:/myjava/com/pomay/test/HelloWorld.calss

	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// 如果父类 加载器没有加载,就读取该文件目录下该类.class文件,即字节码文件是否有数据
			{
				byte[] classData = getClassData(name);
				if (classData == null)// 如果没有读取到数据,抛出异常
				{
					throw new ClassNotFoundException();
				} else
					c = defineClass(name, classData, 0, classData.length);
			}
		}
		return c;
	}

	// 判断该文件目录下该类.class文件,即字节码文件是否有数据
	private byte[] getClassData(String className)
	{
		InputStream is = null;
		ByteArrayOutputStream baos = null;
		try
		{
			// 传一个com.pomay.test.HelloWorld -->
			// f:/myjava/com/pomay/test/HelloWorld.calss
			String path = rootDir + "/" + className.replace(".", "/") + ".class";
			is = new FileInputStream(path);
			baos = new ByteArrayOutputStream();
			byte[] b = new byte[1024];
			int len;
			while ((len = is.read(b)) != -1)
			{
				baos.write(b, 0, len);

			}
			return baos.toByteArray();
		} catch (IOException e)
		{
			e.printStackTrace();
			return null;
		} finally
		{
			if (baos != null)
			{
				try
				{
					baos.close();
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
			if (is != null)
			{
				try
				{
					is.close();
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}

	}

	public static void main(String[] args) throws ClassNotFoundException
	{
		FileSystemClassLoader loader = new FileSystemClassLoader("F:/myjava");
		Class<?> c = loader.findClass("com.pomay.test.HelloWorld");// F:/myjava下的HelloWorld类
		Class<?> c1 = loader.findClass("com.pomay.test.MyDemo");// eclipse里com.pomay.test包下的MyDemo类
		System.out.println(c.getClassLoader());// com.pomay.test.FileSystemClassLoader@15db9742
		System.out.println(c1.getClassLoader());// sun.misc.Launcher$AppClassLoader@73d16e93
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值