您好,登录后才能下订单哦!
# 什么是双亲委派机制
## 目录
1. [引言](#引言)
2. [类加载器基础](#类加载器基础)
3. [双亲委派机制定义](#双亲委派机制定义)
4. [工作流程详解](#工作流程详解)
5. [实现原理分析](#实现原理分析)
6. [优势与设计意义](#优势与设计意义)
7. [打破双亲委派机制](#打破双亲委派机制)
8. [实际应用场景](#实际应用场景)
9. [常见问题与解决方案](#常见问题与解决方案)
10. [总结](#总结)
---
## 引言
在Java虚拟机(JVM)的类加载过程中,**双亲委派机制(Parent Delegation Model)** 是保证Java程序稳定运行的核心设计原则之一。该机制通过层次化的类加载器结构,有效解决了类重复加载、核心API被篡改等关键问题。本文将深入解析这一机制的实现原理、工作流程及其在Java生态中的重要意义。
---
## 类加载器基础
### 类加载器的作用
- 将.class文件加载到JVM内存
- 转换为方法区中的运行时数据结构
- 生成对应的`Class<?>`对象
### Java中的三类加载器
1. **Bootstrap ClassLoader**(启动类加载器)
   - 加载`JAVA_HOME/lib`下的核心类库(如rt.jar)
   - 唯一没有父加载器的加载器
2. **Extension ClassLoader**(扩展类加载器)
   - 加载`JAVA_HOME/lib/ext`目录的扩展类
   - 父加载器为Bootstrap
3. **Application ClassLoader**(应用程序类加载器)
   - 加载用户类路径(ClassPath)上的类
   - 父加载器为Extension
```java
// 查看类加载器示例
public class ClassLoaderDemo {
    public static void main(String[] args) {
        System.out.println(String.class.getClassLoader()); // null (Bootstrap)
        System.out.println(com.sun.crypto.provider.DESKeyFactory.class.getClassLoader()); // ExtClassLoader
        System.out.println(ClassLoaderDemo.class.getClassLoader()); // AppClassLoader
    }
}
“A class loader delegates the search for classes and resources to its parent class loader before attempting to find the class or resource itself.” —— Java官方文档
AppClassLoader收到请求ExtClassLoaderExtClassLoader继续委派给BootstrapClassLoaderBootstrap尝试加载:
ExtClassLoader尝试ExtClassLoader尝试加载:
AppClassLoader尝试AppClassLoader在classpath中查找并加载graph TD
    A[AppClassLoader] --> B[ExtClassLoader]
    B --> C[BootstrapClassLoader]
    C -->|加载失败| B
    B -->|加载失败| A
ClassLoader.loadClass()的典型实现:
protected Class<?> loadClass(String name, boolean resolve) {
    synchronized (getClassLoadingLock(name)) {
        // 1. 检查是否已加载
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            try {
                // 2. 父加载器不为空则委派
                if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    // 3. 父加载器为空则尝试Bootstrap加载
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {}
            
            if (c == null) {
                // 4. 自行查找类
                c = findClass(name);
            }
        }
        return c;
    }
}
安全性保障
避免重复加载
职责分离
当用户自定义java.lang.Object类时:
1. 加载请求最终委派到BootstrapClassLoader
2. Bootstrap已加载过JRE中的Object类
3. 直接返回已加载的Class对象
4. 自定义类永远不会被加载
SPI服务发现(如JDBC驱动加载)
热部署需求
// 通过重写loadClass方法打破委派
public class CustomClassLoader extends ClassLoader {
    @Override
    protected Class<?> loadClass(String name, boolean resolve) {
        // 1. 自定义逻辑优先处理
        if (name.startsWith("com.special.")) {
            return findClass(name);
        }
        // 2. 其他类仍走双亲委派
        return super.loadClass(name, resolve);
    }
}
graph BT
    WebApp1[WebAppClassLoader] --> Common[CommonClassLoader]
    WebApp2[WebAppClassLoader] --> Common
    Common --> Shared[SharedClassLoader]
    Shared --> Server[ServerClassLoader]
    Server --> Bootstrap
@EnableAspectJAutoProxy(proxyTargetClass=true)控制| 异常类型 | 触发阶段 | 常见原因 | 
|---|---|---|
| ClassNotFoundException | 加载阶段 | 类文件不存在 | 
| NoClassDefFoundError | 链接阶段 | 类已加载但依赖缺失 | 
// 热加载示例
public class HotSwap {
    public static void main(String[] args) throws Exception {
        while (true) {
            CustomClassLoader loader = new CustomClassLoader();
            Class<?> clazz = loader.loadClass("com.example.DynamicClass");
            Object instance = clazz.newInstance();
            clazz.getMethod("execute").invoke(instance);
            Thread.sleep(5000);
        }
    }
}
双亲委派机制作为Java类加载体系的核心设计: - 通过层次化委派保证类加载的有序性 - 是Java安全模型的基石之一 - 在保持稳定性的同时允许通过特定方式扩展
随着模块化系统(JPMS)的引入,Java 9+对类加载机制进行了进一步优化,但双亲委派的基本思想仍是理解JVM类加载过程的关键所在。
最佳实践建议:在自定义类加载器时,除非有明确需求,否则应保持双亲委派机制的完整性。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。