ClassLoader类加载机制
文章目录
一、什么是ClassLoader?
ClassLoader类加载器,它的具体作用就是讲Class文件加载到JVM虚拟机中去,程序就可以正常运行了。但是JVM启动的时候并不会一次性加载所有的class文件,而是根据需要去动态加载。
二、Java内置的3类Classloader
1.Bootstrap ClassLoader
java最顶层的、程序引导启动的类加载器,主要加载核心类库:%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等,对应用不可见。
2.Extention ClassLoader
扩展类的加载器,默认家在目录%JRE_HOME%\lib\ext目录下的jar和class文件。
3.AppClassLoader
也称SystemAppClassLoader
加载当前应用的classpath的所有类,即应用程序依赖的jar和本身的class文件中定义的类。
三个类加载器,可以通过指定参数来改变或追加扫描路径
ClassLoader类型 | 参数类型 | 说明 |
---|---|---|
Bootstrap ClassLoader | -Xbootstrapclasspath: | 设置Bootstrap ClassLoader的搜索路径 |
-Xbootstrapclasspath/a: | 把路径添加到已存在搜索路径的后面 | |
-Xbootstrapclasspath/b: | 把路径添加到已存在搜索路径的前面 | |
Extention ClassLoader | -Djava.ext.dir | 设置Bootstrap ClassLoader的搜索路径 |
AppClassLoader | -Djava.class.path=或者-cp-classpath | 设置AppClassLoader的搜索路径 |
三、ClassLoader约定的类加载机制—双亲委托模型
当一个类加载器接收到一个类加载的任务时,不会立即加载,而是将加载任务委托给它的父类加载器去执行,每一层的类都采用相同的方式,直接委托给最顶层的启动类加载器为止。如果父类加载器无法加载委托给它的类,便将类的加载任务退回给下一级类加载器去执行加载。
使用双亲委托机制的好处是:能够有效确保一个类的全局唯一性,当程序中出现多个限定名相同的类时,类加载器在执行加载时,始终只会加载其中的某一个类。
双亲委托模型对于保证JAVA程序的稳定运作很重要,但它的实现却非常简单,实现双亲委托的代码都集中在java.lang.ClassLoader的loadClass()方法中,逻辑清晰易懂:先检查是否已经倍加再过,若没有加载则调用父类加载器的loadClass()方法,若父加载器为空则默认使用启动类加载器作为父加载器。如果父类加载器加载失败,包出ClassNotFoundException异常后,在调用自己的findClass方法进行加载。
时序图解析:
1.一个APPClassLoader查找资源时,先查看缓存中是否存在,缓存有从缓存中获取,否则委托给父类加载器。
2.重复第1步的操作。
3.如果ExtClassLoader也没有加载过,则有BootstrapClassLoader加载,首先查找缓存,没有查到就去扫描自己规定的路径,sun.mic.boot.class下面的路径,找到就返回,否则让子加载器自己加载。
4.Bootstrap ClassLoader如果没有找到,则ExtClassLoader自己在java.ext.dirs路径中扫描,查到就返回,否则继续向下让子加载器查找。
5.ExtClassLoader查不到,AppClassLoader就自己扫描,在java.class.path路径下查找,找到就返回,如果没有找到就让子类扫描。如果没有子类了就会抛出异常。
四、双亲委托模型
双亲委托模型为什么会这样加载?我们还需要了解ClassLoader类,尤其是重要的方法loadClass()、findLoadedClass()、findClass()、defineClass()。
ClassLoader是所有类加载器(BootstrapClassLoader除外,因为它是JVM层面的类加载器)的最顶级基类,他有一个ClassLoader类型parent字段,及它的父类加载器,注意这里不是父类,一个类加载器和父类加载器是组合关系,不是继承关系。
ClassLoader部分方法定义
public abstract class ClassLoader {
private final ClassLoader parent;
public Class<?> loadClass(String name) throws ClassNotFoundException;