首页 > 其他分享 >面试官:什么是双亲委派模型?

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

时间:2023-02-03 08:22:05浏览次数:58  
标签:委派 面试官 Java 模型 应用程序 双亲 加载

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

1.类加载器

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

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

如下图所示:
image.png
这 3 个类加载器的作用如下。

1.1 启动类加载器

启动类加载器(Bootstrap ClassLoader)是由 C++ 实现的,它是用来加载 <JAVA_HOME>\jre\lib\rt.jar 和 resources.jar 等 jar 包的,如下图所示:
image.png
接下来我们写个代码测试一下 rt 类加载器的打印:

public class ClassLoaderExample {
    public static void main(String[] args) {
        // rt 类下的 ClassLoader 打印
        System.out.println("rt classloader:" + String.class.getClassLoader());
    }
}

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

1.2 扩展类加载器

扩展类加载器是用来加载 <JAVA_HOME>\jre\lib\ext 目录下 jar 包的,如下图所示:
image.png
接下来我们使用代码来演示一下 ext 类加载器,示例代码如下:

public class ClassLoaderExample {
    public static void main(String[] args) {
        // ext 类下 classloader 打印
        System.out.println("ext classloader:" +
                sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
    }
}

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

1.3 应用程序类加载器

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

public class ClassLoaderExample {
    public static void main(String[] args) {
        System.out.println("application classloader:" +
                ClassLoaderExample.class.getClassLoader());
    }
}

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

2.双亲委派模型

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

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

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

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

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

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

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 不能通过这个规则进行加载,它需要通过打破双亲委派的模型的方式来加载。

本文已收录到 Gitee 开源仓库《Java 面试指南》,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。Java 面试有它就够了:https://gitee.com/mydb/interview

标签:委派,面试官,Java,模型,应用程序,双亲,加载
From: https://www.cnblogs.com/vipstone/p/17087949.html

相关文章

  • 面试官:你说说 JavaScript 中类型的转换机制
    前言面试官:“你说说JavaScript中类型的转换机制”紧张的萌新:“字符串跟其他类型拼接会变成字符串...”面试官:“...”······大家好,我是CoderBin。又来到了面试官......
  • JVM之类加载子系统与双亲委派机制
    JVM之类加载子系统与双亲委派机制一、类加载子系统1.类加载子系统负责从文件系统或者网络中加载class文件,class文件在文件开头有特定的文件标识,JVM并不是通过检查文件后缀是......
  • 类加载器和双亲委派机制
    类加载器类加载器可以分为三种:引导类加载器(根加载器BootstrapClassLoader):负责加载jre/rt.jar核心类库它本身不是java代码实现的,也不是ClassLoader的子类,获取该......
  • 域内委派攻击
    域委派是指,将域内用户的权限委派给服务账号,使得服务账号能以用户权限开展域内活动。利用委派可获取域管理员权限域委派主要分为三种:非约束性委派约束性委派基于......
  • 被面试官问住了,MySQL两阶段提交是什么鬼?
    “MySQL中既存在redolog,又存在binlog,这是因为BinLog是MySQLServer提供的一种归档日志,其本身并不具备Crash-Safe能力。而RedoLog本身不具备归档能力,他是一种循环写的日......
  • 委派模式——从SLF4J说起
    作者:vivo互联网服务器团队-Xiongyangxin将某个通用解决方案包装成成熟的工具包,是每一个技术建设工作者必须思考且必须解决的问题。本文从业内流行的既有工具包入手,解......
  • 面试官:JVM是如何判定对象已死的?
    本文已收录至Github,推荐阅读......
  • Java类加载器与双亲委派机制
    类加载器顶级类加载器:BootStrapClassLoader负责加载%JAVA_HOME%路径下lib文件夹中的jar包和class文件扩展类加载器:ExtClassLoader负责加载%JAVA_HOME%路径下lib文件夹......
  • 如何用 30s 给面试官讲清楚什么是 Token?
    引言前文介绍了Session-Cookie的认证过程,简单回顾下基本步骤:客户端(浏览器)向服务器发送用户名和密码服务器验证通过后,创建Session对象,在Session中保存该用户相关......
  • 如何用 30s 给面试官讲清楚什么是 Token?
    引言前文介绍了Session-Cookie的认证过程,简单回顾下基本步骤:客户端(浏览器)向服务器发送用户名和密码服务器验证通过后,创建Session对象,在Session中保存该用户相关......