java类加载器有哪些:分四层层级各司其职适配不同加载场景

java类加载器有哪些:分四层层级各司其职适配不同加载场景

前段时间排查线上诡异的类冲突异常,翻遍日志调试代码,才认认真真搞清楚java类加载器有哪些,也彻底改掉了之前模糊笼统的认知,不再把所有类加载工作混为一谈。

最开始学Java的时候,一直天真的以为类加载器就是一个统一的工具,所有的class文件都是被同一个加载器加载,出了类型转换异常、类重复加载的问题,完全摸不着头脑,根本不知道问题根源出在加载器分层上。

压根没考虑过加载器的层级隔离逻辑。

折腾好久才搞明白,JVM原生自带三层基础类加载器,再加上开发者可以手动实现的自定义类加载器,这四类就是开发中所有能接触到的完整类型,每一种的加载范围、优先级、使用场景都完全不一样,不存在重叠混乱的情况。最先接触到的是启动类加载器,这是整个加载体系里最底层的存在,由C++语言实现,并不是Java本身的类,所以在代码里打印它的实例,永远只会输出null。它只负责加载JDK最核心的基础类库,比如rt.jar、java.lang包下的所有核心类,日常业务开发完全触碰不到,也不需要手动操作,是JVM启动时自动执行的底层加载逻辑。

后来才反应过来,第二层的平台类加载器,是JDK9版本更新后替换掉原先扩展类加载器的存在。之前维护老项目时还能见到拓展加载器的痕迹,新版JDK直接整合优化,由平台类加载器负责加载Java平台的拓展类、安全模块类等中间层级的资源。这个加载器同样不用开发者手动调用,属于JVM自动托管的加载层级,唯一的作用就是衔接底层核心加载器和上层应用加载器,补齐中间的类加载空白。

最常用的永远是应用类加载器。

应用类加载器是我们日常开发打交道最多的加载器,也是默认的类加载工具。它专门负责加载我们项目中自定义的业务代码、配置文件,还有通过Maven、Gradle引入的所有第三方依赖jar包。平时写的每一个Controller、Service实体类,引入的工具包、框架包,全部都是由它完成加载。之前遇到的依赖版本冲突、重复类定义报错,全部都是这个加载器加载了多个版本的同名类导致的,这也是开发中最容易出问题、最需要重点关注的加载器。

除了JVM自带的三层原生加载器,最后一类就是自定义类加载器。普通业务项目基本用不上,但做框架开发、热部署、模块隔离、代码加密场景时,必须自己实现加载器。之前做项目热更新功能时,就手动重写了类加载器的loadClass方法,打破默认的双亲委派机制,才能实时加载修改后的class文件。像Tomcat、Spring框架的类隔离、热加载功能,全部都是基于自定义类加载器实现的,它的核心价值就是打破原生加载器的固定规则,适配个性化的业务需求。

从懵懂以为只有一种加载器,到分清三层原生加载器,再到理解自定义加载器的拓展作用,才算真正吃透了Java类加载的基础逻辑,很多诡异的报错也终于有了清晰的排查方向。

保存完调试笔记,随手清空了控制台密密麻麻的报错日志。

了解更多百科知识请访问 百科