自定义实现类加载器+打破双亲委派模型思路分析
周志明老师新书:凤凰架构
public class MyClassloaderTest {
static class MyClassLoader extends ClassLoader {
private String classPath;
public MyClassLoader(String classPath) {
this.classPath=classPath;
}
/**
* 双亲委派机制实现逻辑
* 本方法打破双亲委派机制
*/
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
/**
* 原双亲委派模型逻辑-->交给父类
*/
// try {
// if (parent != null) {
// c = parent.loadClass(name, false);
// } else {
// c = findBootstrapClassOrNull(name);
// }
// } catch (ClassNotFoundException e) {
// // ClassNotFoundException thrown if class not found
// // from the non-null parent class loader
// }
if (!name.startsWith("cn.test")){
//比如Object.class就要双亲委派给根类加载器去加载
c=super.loadClass(name);
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
return c;
}
}
/**
* 加载class文件到内存中
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = loadByte(name);
//将字节数组转换为Class对象
return defineClass(name, bytes, 0, bytes.length);
}
/**
* 解析文件,读取到byte数组中
*/
private byte[] loadByte(String name) {
name = name.replaceAll("\\.", "/");
name =classPath+"/src/main/java/"+name+".class";
FileInputStream fileInputStream = null;
try {
fileInputStream= new FileInputStream(name);
int len = fileInputStream.available();
byte[] bytes=new byte[len];
fileInputStream.read(bytes);
return bytes;
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return new byte[0];
}
}
public static void main(String[] args) throws Exception{
MyClassLoader myClassLoader = new MyClassLoader("D:/ideaProject/untitled");
Class<?> aClass = myClassLoader.loadClass("cn.test.classloader.LoaderModelTest");
Object obj = aClass.newInstance();
Method method = aClass.getDeclaredMethod("sout", null);
method.setAccessible(true);
method.invoke(obj, null);
System.out.println(aClass.getClassLoader().getClass().getName());
System.out.println(aClass.getClassLoader().getParent().getClass().getName());
}
}
不打破双亲委派模型(不重写loadClass)运行结果:
打破双亲委派模型(重写loadClass)运行结果: