前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >面试官:什么是双亲委派模型?

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

作者头像
程序猿川子
发布于 2023-02-27 09:37:29
发布于 2023-02-27 09:37:29
37300
代码可运行
举报
运行总次数:0
代码可运行

双亲委派模型是 Java 类加载器的一种工作模式,通过这种工作模式,Java 虚拟机将类文件加载到内存中,这样就保证了 Java 程序能够正常的运行起来。那么双亲委派模型究竟说的是啥呢?接下来我们一起来看。

1.类加载器

双亲委派模型针对的是 Java 虚拟机中三个类加载器的,这三个类加载器分别是:

  1. 启动类加载器(Bootstrap ClassLoader)
  2. 扩展类加载器(Extension ClassLoader)
  3. 应用程序类加载器(Application ClassLoader)

如下图所示:

这 3 个类加载器的作用如下。

1.1 启动类加载器

启动类加载器(Bootstrap ClassLoader)是由 C++ 实现的,它是用来加载 <JAVA_HOME>\jre\lib\rt.jar 和 resources.jar 等 jar 包的,如下图所示:

接下来我们写个代码测试一下 rt 类加载器的打印:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ClassLoaderExample {
    public static void main(String[] args) {
        // rt 类下的 ClassLoader 打印
        System.out.println("rt classloader:" + String.class.getClassLoader());
    }
}
复制代码

以上程序的执行结果如下图所示:

问题来了,为什么打印的不是“Bootstrap ClassLoader”而是 null 呢? 这是因为启动类加载器(Bootstrap ClassLoader)是由 C++ 实现的,而这个 C++ 实现的类加载器在 Java 中是没有与之对应的类的,所以拿到的结果是 null。

1.2 扩展类加载器

扩展类加载器是用来加载 <JAVA_HOME>\jre\lib\ext 目录下 jar 包的,如下图所示:

接下来我们使用代码来演示一下 ext 类加载器,示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ClassLoaderExample {
    public static void main(String[] args) {
        // ext 类下 classloader 打印
        System.out.println("ext classloader:" +
                sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
    }
}
复制代码

以上程序的执行结果如下图所示:

1.3 应用程序类加载器

应用程序类加载器是用来加载 classpath 也就是用户的所有类的,接下来我们写代码测试一下应用程序类加载器的打印,实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ClassLoaderExample {
    public static void main(String[] args) {
        System.out.println("application classloader:" +
                ClassLoaderExample.class.getClassLoader());
    }
}
复制代码

以上程序的执行结果如下图所示:

2.双亲委派模型

双亲委派模型的执行流程是这样的: 1、当加载一个类时,会先从应用程序类加载器的缓存里查找相应的类,如果能找到就返回对象,如果找不到就执行下面流程;

2、在扩展加载器缓存中查找相应的类,如果能找到就返回对象,如果找不到就继续下面流程;

3、在启动类加载器中查询相应的类,如果找到就返回对象,如果找不到就继续下面流程;

4、在扩展加载器中查找并加载类,如果能找到就返回对象,并将对象加入到缓存中,如果找不到就继续下面流程;

5、在应用程序类加载器中查找并加载类,如果能找到就返回对象,并将对象加入到缓存中,如果找不到就返回 ClassNotFound 异常。

加载流程如下图所示:

一般“双亲”指的是“父亲”和“母亲”,而在这里“双亲”指的是类加载类先向上找,再向下找的流程就叫做双亲委派模型。

3.优缺点分析

3.1 优点

双亲委派模型的优点有两个: 1、安全。 2、避免重复加载。

3.1.1 安全

在安全方面的表现时,当使用双亲委派模型时,用户就不能伪造一些不安全的系统类了,比如 jre 里面已经提供了 String 类在启动类加载时加载,那么用户自定义再自定义一个不安全的 String 类时,按照双亲委派模型就不会再加载用户定义的那个不安全的 String 类了,这样就可以避免非安全问题的发生了。

3.1.2 避免重复加载

使用双亲委派模型也可以避免一个类被重复加载,当一个类被加载之后,因为使用的双亲委派模型,这样不会出现多个类加载器都将同一个类重复加载的情况了。

3.2 缺点

双亲委派模型的典型问题是加载 SPI 实现类的场景,比如 JNDI(Java Naming and Directory Interface,Java 命名与目录接口)服务,它的代码由启动类加载器去加载(在 JDK 1.3 时放进 rt.jar),但 JNDI 的目的就是对资源进行集中管理和查找,它需要调用独立厂商实现部部署在应用程序的 classpath 下的 JNDI 接口提供者(SPI, Service Provider Interface)的代码,但启动类加载器不可能“认识”之些代码,这就双亲委派模型的问题,JDBC 也是同样的问题。

总结

双亲委派模型是和 Java 中多个类加载器(启动类加载器、扩展加载器、应用程序类加载器)的运行规则,通过这个(双亲委派模型)规则可以避免类的非安全问题和类被重复加载的问题,但它也遇到了一些问题,比如 JNDI 和 JDBC 不能通过这个规则进行加载,它需要通过打破双亲委派的模型的方式来加载。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
阿里面试:什么地方违反了双亲委派模型
类加载机制是指将类的class文件读入到内存,并为之创建一个java.lang.Class对象。中间对数据做了 校验,转换解析和初始化等操作。
哲洛不闹
2019/08/20
2.6K0
阿里面试:什么地方违反了双亲委派模型
双亲委派模型:大厂高频面试题,轻松搞定
文章内容相对较长,但如果你希望对 Java 的类加载过程有个更深入的了解,同时增加自己的面试技能点,请耐心读完......
用户4172423
2019/09/04
6490
双亲委派模型:大厂高频面试题,轻松搞定
【jvm】通过JDBC为例谈谈双亲委派模型的破坏
双亲委派模型并不是一个强制约束模型,而是java设计者推荐给开发者的类加载实现方式;但是也会有例外; 今天我们主要来讲一讲 类似于SPI这种设计导致的双亲委派模型被“破坏”的情况;
石臻臻的杂货铺[同名公众号]
2021/07/14
1.2K0
面试官:说说如何打破或违反双亲委派!
SPI的全名为Service Provider Interface,主要是应用于厂商自定义组件或插件中,在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java SPI机制的思想:我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块、xml解析模块、jdbc模块等方案。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。
业余草
2021/12/06
2.2K0
面试官:说说如何打破或违反双亲委派!
聊聊类加载器与双亲委派模型
我们经常会在面试中遇到有关类加载器的问题,而作为一名Java开发人员应该了解类加载器如何工作?双亲委派模型是什么?如何打破双亲委派?为什么打破?等等。所以今天的主题就是聊一聊类加载器。
pjmike
2020/03/22
8530
类加载器以及双亲委派模型
首先我们来描述一个小说场景,通过这个场景在去理解我们相关的类加载器的执行以及双亲委派模型。
胖虎
2019/06/26
4600
类加载器以及双亲委派模型
类加载过程,双亲委派模型?
java通过字节码和JVM机制,提供了强大的跨平台能力,理解Java的类加载机制能让我们更加了解java的运行过程
袁新栋-jeff.yuan
2020/08/26
3290
类加载过程,双亲委派模型?
相关推荐
阿里面试:什么地方违反了双亲委派模型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验