默认三个不同的类加载器
-
BootstrapClassLoader:加载环境变量 --sun.boot.class.path的资源文件
-
ExtClassLoader:加载环境变量 --java.ext.dirs的资源文件
-
AppClassLoader:加载环境变量 --java.class.path的资源文件
打印结果 (内容太多了)
三个类加载器哪加载设置的呢?Launcher
在launcher中静态变量设置了 bootClassPath的路径
构造方法获取了Ext和App类加载器,并设置了当前线程上下文加载器为app类加载器,ExtClassLoader和AppClassLoader为Launcher中的两个静态内部类
ExtClassLoader
AppClassLoader
- 可见加载路径,并且都默认设置为了并行加载
谈到并行加载,classloader加载流程中看看
ClassLoader类中几个重要方法:
defineClass 方法:用来将byte字节流解析成JVM能识别的Class对象
findClass方法:寻找类,由子类覆盖实现
findLoadClass方法:判断类是否被加载过
resolveClass方法:类链接,解析类
loadClass方法:加载类的对象 loadClass("com.frank.test.Test")
自定义ClassLoader
1.重写findClass方法,改变加载的类路径
2.调用defindClass方法实例化类
源码加载流程
蓝框内获取锁稍后讲;
- 蓝框中findLoaderClass(name)
- 红框中双亲委派机制,ClassLoader在加载类的时候,会先交由它的父ClassLoader加载,只有当父ClassLoader加载失败的情况下,才会尝试自己去加载。这样可以实现部分类的复用,又可以实现部分类的隔离,因为不同ClassLoader加载的类是互相隔离的
- 绿框中自己去加载
- 每个classloader都有一个类似map的容器记录加载的class保证相互隔离
加载获取锁流程
- 串行加载锁:classloader本身
- 并行加载锁:被加载的class,粒度更细了
parallelLockMap 在哪的赋值呢,还记得默认加载器静态方法中设置的并行加载吗,判断内容跟那有关,等同true,所以构造加载器时new ConCurrentHashMap