JVM-类加载(5)
类加载器
以 jdk8 为例:
名称 | 加载什么地方的类 | 说明 |
---|---|---|
Bootstrap ClassLoader | JAVA_HOME/jre/lib | 无法直接访问 |
Extension ClassLoader | JAVA_HOME/jre/lib/ext | 上级为Bootstrap,显示为null |
Application ClassLoader | classpath | 上级为Extension |
自定义类加载 | 自定义 | 上级为Application |
启动类加载器
- -Xbootclasspath 表示设置 bootclasspath
- java -Xbootclasspath:
完全替换jre下的lib - java -Xbootclasspath/a:<追加路径> 追加一个路径(后追加)
- java -Xbootclasspath/p:<追加路径> 追加一个路径(前追加)
- java -Xbootclasspath:
扩展类加载器
顺序:启动类 > 扩展类 > 应用类
调用类加载器的loadClass方法时,查找类的规则 —— 双亲委派模式
这里的双亲,理解为上级更加合适,他们之间并没有继承关系
规则:
- 1-检查该类是否已经加载
- 2-有上级则委派上级 loadClass
- 3-没有上级,委派启动类加载器Bootstrap ClassLoader
- 4-每一层都找不到,调用findClass方法(每个类加载器自己扩展)加载
线程上下文类加载器
我们使用过JDBC,其中需要
Class.forName("com.mysql.jdbc.Driver")
但是如果不写上面的代码,我们依旧能够让驱动正常加载
DriverManager部分源码:
public class DriverManager {
// 注册驱动集合
private final static CopyOnWriterArrayList<DriverInfo> registeredDrivers = new CopyOnWriterArrayList();
// 初始化驱动
static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
}
我们通过
System.out.println(DriverManager.class.getClassLoader());
得到结果为null,可知其类加载器是 Bootstrap ClassLoader,会在 JAVA_HOME/jre/lib 下搜索类
但在此路径下并没有显示有相关的驱动jar包,那么它是如何正确加载到的呢?
原因在于 loadInitialDrivers() 方法:
JDK在某些情况下需要打破双亲委派模式,有时候会调用应用程序类加载器来进行加载,否则有些类是找不到的
在这个方法中使用了 Service Provider Interface(SPI)接口进行解耦合
使用要求在jar包中新增一个 META-INF 目录,目录下services目录存放接口全限定名文件用于存放接口的实现类名
ServiceLoader.load方法:
public static <S> ServiceLoader<S> load(Class<S> service) {
// 获取线程上下文类加载器
ClassLoader c1 = Thread.currentThread().getContextClassLoader();
return ServiceLoader.load(service c1);
}
线程上下文类加载器是当前线程使用的类加载器,默认就是应用程序类加载器,
它内部又是由 Class.forName调用了线程上下文类加载器完成类加载,
具体代码在ServiceLoader 的内部类 LazyIterator中……
自定义类加载器
什么时候需要自定义类加载器:
- 想加载非classpath 随意路径中的类文件
- 都是通过接口来使用实现,希望解耦合时,常用在框架设计
- 这些类希望予以隔离,不同应用的同名类都可以加载,不冲突,常见于 tomcat 容器
使用步骤:
- 1 继承 ClassLoader 父类
- 2 要遵从双亲委派机制,重写 findClass 方法
- 注意不是重写 loadclass 方法,否则不会走双亲委派机制
- 3 读取类文件的字节码
- 4 调用父类的defineClass 方法来加载类
- 5 使用者调用该类加载器的 1oadClass 方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异