自定义文件系统类加载器

来源:互联网 发布:淘宝卖家报复的买家 编辑:程序博客网 时间:2024/06/06 10:05

自定义类加载器的流程:

继承: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.calssprivate String rootDir;public FileSystemClassLoader(String rootDir){super();this.rootDir = rootDir;}@Overrideprotected 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();} elsec = 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.calssString 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 blocke.printStackTrace();}}if (is != null){try{is.close();} catch (IOException e){// TODO Auto-generated catch blocke.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@15db9742System.out.println(c1.getClassLoader());// sun.misc.Launcher$AppClassLoader@73d16e93}}




原创粉丝点击