类加载与双亲委派
为什么 JDBC 驱动不需要
Class.forName()了?为什么同一个 jar 包在两个 ClassLoader 中加载会报ClassCastException?答案都在类加载机制里。
一、类加载的 7 个阶段
- 1.1 加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载
- 1.2 哪些阶段是交叉进行的
- 1.3 类加载的触发时机——主动引用 vs 被动引用
二、类加载器层次结构
- 2.1 Bootstrap ClassLoader——加载
<JAVA_HOME>/lib - 2.2 Extension ClassLoader(JDK 8)→ Platform ClassLoader(JDK 9+)
- 2.3 Application ClassLoader——加载 classpath
- 2.4 自定义 ClassLoader——什么时候需要
三、双亲委派模型
- 3.1 委派流程:子 → 父 → Bootstrap(向上委派,向下查找)
- 3.2
loadClass()源码分析 - 3.3 为什么这样设计——避免重复加载 + 核心类安全
四、破坏双亲委派的经典案例
- 4.1 JDBC 驱动的加载——SPI 机制
- 4.2 Tomcat 的 WebappClassLoader——应用隔离
- 4.3 热部署/热替换的实现原理
五、SPI 机制深入
- 5.1
ServiceLoader.load()源码走读 - 5.2
META-INF/services/文件的约定 - 5.3 SPI 的缺陷——无法按需加载
- 5.4 SPI vs API 的区别
六、线程上下文类加载器
- 6.1
Thread.currentThread().getContextClassLoader() - 6.2 为什么需要它——打破双亲委派的”后门”
- 6.3 使用场景与注意事项
七、类卸载
- 7.1 类的卸载条件(GC Root 不可达)
- 7.2 自定义 ClassLoader 的卸载
- 7.3 方法区/元空间的类信息回收
八、实际案例分析
- 8.1
ClassCastException:同一个类在不同 ClassLoader 中的”不同身份” - 8.2
NoClassDefFoundErrorvsClassNotFoundException - 8.3 排查工具:
-verbose:class查看加载过程
九、总结
- 双亲委派的本质是”安全 + 复用”
- SPI 是”必需的破例”
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 谜思录!