高级java每日一道面试题-2024年10月9日-JVM篇-什么是双亲委派模型?

如果有遗漏,评论区告诉我进行补充

面试官: 什么是双亲委派模型?

我回答:

双亲委派模型(Parent Delegation Model)是Java类加载器(ClassLoader)的一种工作模式。这种模型确保了Java类的加载过程具有良好的层次结构和安全性,避免了类的重复加载,并且能够防止核心类库被恶意替换。

双亲委派模型的工作原理

双亲委派模型的核心思想是:当一个类加载器需要加载某个类时,它首先将加载请求委派给父类加载器。如果父类加载器无法加载该类,则当前类加载器自己尝试加载。这个过程会一直向上追溯,直到顶层的启动类加载器。

具体流程如下:

  1. 当加载一个类时,会先从应用程序类加载器的缓存里查找相应的类。如果能找到,就返回该类的对象;如果找不到,则执行下面的流程。
  2. 在扩展类加载器缓存中查找相应的类。如果能找到,就返回该类的对象;如果找不到,则继续下面的流程。
  3. 在启动类加载器中查询相应的类。如果找到,就返回该类的对象;如果找不到,则继续下面的流程。
  4. 在扩展类加载器中查找并加载类。如果能找到,就返回该类的对象,并将对象加入到缓存中;如果找不到,则继续下面的流程。
  5. 在应用程序类加载器中查找并加载类。如果能找到,就返回该类的对象,并将对象加入到缓存中;如果找不到,就返回ClassNotFound异常。

Java中的类加载器

Java中有三种主要的类加载器:

  1. Bootstrap ClassLoader(启动类加载器)

    • 这是最顶层的类加载器,由C++编写,是JVM的一部分。
    • 它负责加载<JAVA_HOME>/lib目录下的核心Java类库(如rt.jar),或者被-Xbootclasspath参数指定的路径中的所有类。
    • Bootstrap ClassLoader并不是java.lang.ClassLoader的实例,所以你不能通过Java代码直接获取到它。
  2. Extension ClassLoader(扩展类加载器)(也称为Platform ClassLoader):

    • sun.misc.Launcher$ExtClassLoader实现。
    • 它负责加载<JAVA_HOME>/lib/ext目录下的扩展类库,或者被java.ext.dirs系统属性所指定的路径中的所有类。
  3. Application ClassLoader(应用程序类加载器)(也称为System ClassLoader):

    • sun.misc.Launcher$AppClassLoader实现。
    • 它负责加载应用程序的类路径(ClassPath)里所指定的类,通常是环境变量CLASSPATH或通过命令行参数-classpath-cp指定的路径中的类。
  4. Custom ClassLoader(自定义类加载器)

    • 如果应用程序需要,可以通过继承java.lang.ClassLoader类实现自己的类加载器,以满足一些复杂的场景需求。

双亲委派模型的优点

  1. 安全性 :防止用户自定义的类替换核心API类。例如,即使你在类路径下放置了一个名为java.lang.Object的类,也不会被加载,因为这个类名已经被Bootstrap ClassLoader加载过了。
  2. 一致性:确保核心类库的类在程序的各种类加载器环境中都是同一个版本,避免了类的重复加载。
  3. 简化性:开发者不需要关心类的具体加载过程,只需要将类放到类路径下即可,类加载器会自动处理加载逻辑。

双亲委派模型的作用

  1. 安全:通过双亲委派模型,Java类库和应用程序类可以被有效地隔离开。用户不能伪造一些不安全的系统类,从而避免了非安全问题的发生。
  2. 避免重复加载:使用双亲委派模型可以避免一个类被重复加载。当一个类被加载之后,由于使用了双亲委派模型,不会出现多个类加载器都将同一个类重复加载的情况。
  3. 支持类的隔离和版本管理:通过双亲委派模型,不同的类加载器可以为相同名称的类创建额外的命名空间。这样,相同名称的类可以并存在Java虚拟机中,只需要用不同的类加载器来加载它们即可。这实现了类的隔离和版本管理。

双亲委派模型的典型问题

  • 尽管双亲委派模型具有诸多优点,但在某些场景下也会遇到问题。例如,在加载SPI(Service Provider Interface)实现类的场景(如JNDI、JDBC等)中,由于启动类加载器无法识别应用程序classpath下的SPI实现类,因此需要通过打破双亲委派模型的方式来加载这些类。
优点
  • 安全性:通过确保核心 Java API 类由启动类加载器加载,防止了用户自定义类的潜在冲突和篡改。
  • 避免重复加载:由于类加载请求总是向上委派,可以确保同一个类只被加载一次,即使有多个类加载器存在。
缺点
  • 对于某些特殊场景,如插件架构,双亲委派模型可能不适用,因为它限制了类加载器加载来自不同源的类的能力。在这些情况下,可能需要自定义类加载器来绕过双亲委派模型。

总结

双亲委派模型是Java类加载机制的一个重要组成部分,它保证了类的加载顺序和唯一性,提高了系统的安全性和稳定性。理解这一模型对于深入掌握Java类加载机制以及进行相关开发和调试非常重要。

相关推荐
IT毕设实战小研26 分钟前
基于Spring Boot校园二手交易平台系统设计与实现 二手交易系统 交易平台小程序
java·数据库·vue.js·spring boot·后端·小程序·课程设计
泉城老铁37 分钟前
Spring Boot 中根据 Word 模板导出包含表格、图表等复杂格式的文档
java·后端
极客BIM工作室43 分钟前
谈谈《More Effective C++》的条款30:代理类
java·开发语言·c++
孤狼程序员43 分钟前
【Spring Cloud 微服务】1.Hystrix断路器
java·spring boot·spring·微服务
RainbowSea1 小时前
伙伴匹配系统(移动端 H5 网站(APP 风格)基于Spring Boot 后端 + Vue3 - 04
java·spring boot·后端
用户84913717547161 小时前
JustAuth实战系列(第11期):测试驱动开发 - 质量保证与重构实践
java·设计模式·单元测试
RainbowSea1 小时前
伙伴匹配系统(移动端 H5 网站(APP 风格)基于Spring Boot 后端 + Vue3 - 03
java·spring boot·后端
心月狐的流火号2 小时前
Java SPI 机制与 Spring Boot 自动装配原理
java·spring boot
AAA修煤气灶刘哥2 小时前
面试必问:聊一聊Spring中bean的循环依赖问题 ?——从原理到避坑
java·后端·程序员
星火飞码iFlyCode2 小时前
真实案例 | 如何用iFlyCode开发Webpack插件?
java·python·编辑器