1. 什么是双亲委派
双亲委派(双亲优先)是Java 类加载器的一种工作机制,用于保护Java程序的安全性和稳定性。根据双亲委派模型,当一个类加载器需要加载某个类时,它首先将这个任务委派给它的父类加载器,只有当父加载器无法加载时,才由该加载器自己尝试加载。如果都无法加载,会委派给引导类加载器(Bootstrap Class Loader)进行加载。
2. 类加载器
2.1 什么是类加载器
类加载器(Class Loader)是 JVM 的一部分,主要负责将 Java 类字节码动态的加载到内存中,也可以说是加载到 JVM 中
2.2 类加载器的分类
JVM 在运行的时候,类加载器组成了一个层级关系每个类加载器分别去加载不同作用范围的 JAR 包
-
引导类加载器(Bootstrap Class Loader):它是Java虚拟机的一部分,负责加载Java类库,也就是%{JDK_HOME} lib 下的 rt.jar、resources.jar、 java、javax、sun 等开头的类以及其他核心类。它是最高层次的类加载器,用于加载 Java 平台自身的类库。由于引导类加载器是由本地代码实现的,所以在Java程序中无法直接获取引导类加载器的引用。
-
扩展类加载器(Extension Class Loader):它是Java虚拟机的一部分,负责加载Java的扩展类库,也就是%{JDK_HOME} lib ext目录下的jar包和class文件。
-
系统类加载器(System Class Loader):也称为应用类加载器(Application Class Loader),它是负责加载应用程序 classpath 上指定的 JAR 包和类文件。在Java中,默认情况下,系统类加载器是由 sun.misc.Launcher$AppClassLoader 实现的,是用户自定义的类加载器的默认父加载器。
-
用户自定义类加载器(User-defined Class Loaders):除了上述三个主要的类加载器,Java 还提供了一些机制,允许开发者自定义类加载器。通过自定义类加载器,可以实现一些特殊的加载需求,如从数据库加载类、动态生成类等。用户自定义的类加载器需要继承自 java.lang.ClassLoader 类,并重写其父类提供的加载方法。
3. 双亲委派机制
所谓的父委托模型,就是按照类加载器的层级关系,逐层进行委派。
类加载器通常按照父子关系层次结构进行组织,每个类加载器都有一个父加载器(除了根加载器),通过委派机制,当一个类加载器需要加载某个类时,它首先会委派给父加载器尝试加载,只有当父加载器无法加载时,才由该加载器自己尝试加载。
简单来说,就是当需要加载一个 class 文件的时候,首先会把这个class 的查询和加载委派给父加载器去执行,如果父加载器都无法加载,再尝试自己来加载这个class。
4. 双亲委派机制的作用
安全性,因为这种层级关系实际上代表的是一种优先级,也就是所有类的加载,都会优先给引导类加载器进行加载。这样对于核心类库中的类,就没办法去破坏或者篡改。也就是说,如果写一个 java.lang.String,最终还是会交给启动类加载器。再加上每个类加载器的作用范围,那么自己写的 java.lang.String 就没办法去覆盖类库中类,也就保证了Class的安全性。
所以,这种层级关系的设计,可以避免重复加载导致程序混乱的问题。因为每个加载器都有一个明确的父加载器,使得类的加载可以按照一定的优先级进行,保证了类加载的有序性。