JVM类加载器的双亲委派模型

双亲委派模型

站在Java虚拟机的角度来看,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap
ClassLoader),这个类加载器使用C++语言实现,是虚拟机自身的一部分;另外一种就是其他所有
的类加载器,这些类加载器都由Java语言实现,独立存在于虚拟机外部,并且全都继承自抽象类
java.lang.ClassLoader。
自JDK 1.2以来,Java一直保持着三层类加载器、双亲委派的类加载架构。三层类加载器为(JDK9之前):启动类加载器,扩展类加载器,应用程序类加载器。
在这里插入图片描述
如果一个类加载器收到了加载类请求,它不会自己加载会将这个请求交由父类去加载,如过父类没加载成功,它才会去尝试加载。每一个层次的类加载器都是如此。

判断两个类是否一致的前提是他们必须是同一个类加载器加载的,否则即使他们是同一个类也不一致。

  • 启动类加载器
    加载<JAVA_HOME>\lib目录,或者被-Xbootclasspath参数所指定的路径中存放的,而且是Java虚拟机能够识别的(按照文件名识别,如rt.jar、tools.jar,名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机的内存中。
  • 扩展类加载器
    它负责加载<JAVA_HOME>\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有的类库。
  • 应用程序类加载器
    它负责加载用户类路径(ClassPath)上所有的类库,开发者同样可以直接在代码中使用这个类加载器。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

JDK9之后引入了模块化系统,所以扩展类加载器自然而然被平台类加载器(Platform Class Loader)取代。
在这里插入图片描述
在将类加载给父类之前,要先判断该类是否能够归属到某一个系统模块中,如果可以找到这样的归属关系,就要优先委派给负责那个模块的加载器完成加载,

破坏双亲委派模型

  • 自定义一个类加载器,重写loadClass()即可。
  • 如果在父类加载器中加载内容想要加载用户的代码资源,如何解决?
    为了解决这个困境,Java的设计团队只好引入了一个不太优雅的设计:线程上下文类加载器(Thread Context ClassLoader)。这个类加载器可以通过java.lang.Thread类的setContext-ClassLoader()方法进行设置。Java中涉及SPI(Service Provider Interface)的加载基本上都采用这种方式来完成,例如JNDI、JDBC、JCE、JAXB和JBI等。
  • OSGi实现模块化热部署。OSGI类加载过程 将委派类和java.*类交由父类加载器加载,其他类在平级类加载器中查找是否能加载。

深入理解Java虚拟机(周志明)阅读笔记,理解有限,如有错误还望指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值