类加载器[3]自定义类加载器[1]:突破父类委托机制
2017-03-06 15:44
155 查看
如果要突破父类委托机制,需要重写loadClass()方法。
如下的例子,当遇到某个类名的时候,会先自己尝试加载,如果自己加载不到,再交由父加载器加载。
Java Code
package com.bjsxt.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class CustomClassLoader extends ClassLoader { private String rootDir; public CustomClassLoader(String rootDir) { this.rootDir = rootDir; } // 从ClassLoader复制过来修改 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {//这里的ClassNotFoundException是有parent.loadClass()抛出的 synchronized (getClassLoadingLock(name)) { // 判断当前类加载器是否已经加载该类 Class<?> c = findLoadedClass(name); if (c == null) {// 未加载//尝试去加载 c = findClass(name); if (c == null) {//加载不到,交由父加载器去加载 ClassLoader parent = getParent(); if(parent!=null) return parent.loadClass(name);//here } } // 已经加载 if (resolve) { resolveClass(c); } return c; } } @Override protected Class<?> findClass(String name){ // 从自定义目录读取文件,转化为一个字节数组 byte[] classData = loadClassBytes(name); if (classData == null) { // throw new ClassNotFoundException(); //这个地方就不再抛出异常了 System.out.println("CustomClassLoader cannot load "+name+", try parent."); return null; } else { Class c = defineClass(name, classData, 0, classData.length); return c; } } private byte[] loadClassBytes(java.lang.String name) { String path = rootDir + "/" + name.replace(".", "/") + ".class"; InputStream is = null; ByteArrayOutputStream baos = null; try { is = new FileInputStream(path); baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int ret = 0; while ((ret = is.read(buffer)) != -1) { baos.write(buffer, 0, ret); } return baos.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace();//这里输出FileNotFoundException } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) is.close(); if (baos != null) baos.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } } |
依然使用之前的HelloWorld.class来测试。
执行输出语句的时候,会遇到
java.lang.Object
java.lang.System
java.io.PrintStream
CustomClassLoader会先尝试加载,加载不到再交由父类加载器加载。(AppClassLoader,并回归正常机制。)
相关文章推荐
- java类加载器学习2——自定义类加载器和父类委托机制带来的问题/JAVA类加载的委托模型/Java的委托
- 类加载器[2]父类委托机制[1]
- 关于Java类加载父类委托机制 /双亲委派模型(附两道面试题)
- java类加载器学习2——自定义类加载器和父类委托机制带来的问题/JAVA类加载的委托模型/Java的委托
- 父类委托机制详解(全盘负责委托机制 )
- JVM笔记7:类加载器与上级委托机制
- Java类加载器学习2——自定义类加载器和父类委托机制带来的问题
- java类加载器学习2――自定义类加载器和父类委托机制带来的问题
- java类的生命周期4类加载的父亲委托机制
- 关于JAVA的内省JavaBean、类加载器、类加载器的委托机制以及代理
- JAVA类加载机制以及如何自定义类加载器
- 类的加载及双亲委托机制
- 突破SafeSEH机制之三——利用加载模块之外的地址绕过SafeSEH
- 类加载机制:全盘负责和双亲委托
- JVM(九) 类加载的父亲委托机制
- 深入理解ClassLoader—类的父委托加载机制
- Java中类的加载机制---父类和子类的多态调用
- 类加载机制:全盘负责和双亲委托
- 【类加载器】————类加载器之间的父子关系以及管辖范围【委托机制】
- 类加载器及其委托机制的深入分析