阿里面试:什么地方违反了双亲委派模型

在开讲双亲委派模型之前,我们先要了解一下类加载机制

类加载机制是指将类的class文件读入到内存,并为之创建一个java.lang.Class对象。中间对数据做了 校验,转换解析和初始化等操作。

一般情况下我们说了有三种加载器:

  • 最基础:Bootstrap ClassLoader(加载JDK的/lib目录下的类)
  • 次基础:Extension ClassLoader(加载JDK的/lib/ext目录下的类)
  • 普通:Application ClassLoader(程序自己classpath下的类)

图片来源于网络

双亲委派模型要求如果一个类可以被委派最基础的ClassLoader加载,就不能让高层的ClassLoader加载。

举个例子:我们实际中用到的一些类如:String,Object等,都是来自于jdk的lib下的rt.jar包,但是如果我们有工作需要在自己的项目中也创建相同名称的类,我们如何来区分呢,双亲委派就完美的解决了这个问题,BootStrap加载rt.jar 包,剩下的由它的子加载器下的子加载器来加载。当然这里的父子不是指的一般意义上的父类和子类。

双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委派父类加载器去完成。每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个请求(他的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

在很多的时候面试官会问我们如何破坏双亲委派模型和为什么要破坏它

在实际的应用中双亲委派解决了java 基础类统一加载的问题,但是却着实存在着一定的缺席。jdk中的基础类作为用户典型的api被调用,但是也存在被api调用用户的代码的情况,典型的如SPI代码。

SPI机制简介 SPI的全名为Service Provider Interface,主要是应用于厂商自定义组件或插件中。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java SPI机制的思想:我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块、xml解析模块、jdbc模块等方案。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

所以jdk开发人员就引入了线程上下文类加载器(Thread Context ClassLoader),这类类加载器可以通过java.lang.Thread 类的setContextClassLoader方法进行设置。

其实在jdbc的使用中,我们很好的体会到它的作用,我们平时看到的mysql的加载是这个样子的:

在以上的代码中就实现了注册mysql驱动和获取数据库连接。

以上的代码是DriverManager 的初始化方法loadInitialDrivers,大家可以从中看到先是获取jdbc.drivers属性,得到类的路径。然后通过系统类加载器加载。

注意driversIterator.next()最终就是调用Class.forName(DriverName, false, loader)方法,也就是最开始我们在第一张图中注释掉的那一句代码。

对于自己加载不了的类怎么办,直接用线程上下类加载器加载,通过

ClassLoader cl = Thread.currentThread().getContextClassLoader();

这条语句获取本地线程然后实现上下类加载。牛逼了,所以这个地方Bootstrap Classloader加载器拿到了Application ClassLoader加载器应该加载的类,就打破了双亲委派模型

前文章释疑:

地址:面试官:是不是所有的对象和数组都会在堆内存分配空间

在前面的一篇文章中有讲到我们在执行逃逸分析的实验中还有8万多的对象并没有逃逸,还是被创建到堆中,形成实例。如果从理论来出发讲肯定在一个方法内的创建对象语句是要被建到栈中,随着栈帧的移动而消除的。但是实际中,一个完美判断对象逃逸的机制是非常耗时和耗性能的,所以虚拟机采用不是非常准确的但时间压力较小的算法,导致一部分对象并没有逃逸。

本文分享自微信公众号 - java一日一条(mjx_java)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT开发技术与工作效率

正则表达式高级

正则表达式高级 ——《精通正则表达式》 +Java/Go/Python官方文档 +多年经验 +实验结果 知识整理

15020
来自专栏Java技术栈

还抱着 Java 8 不放,也是醉了!

原文:https://dzone.com/articles/beyond-java-8

9820
来自专栏Java学习录

SpringIOC源码解析(上)

本文会分析Spring的IOC模块的整体流程,分析过程需要使用一个简单的demo工程来启动Spring,demo工程我以备好,需要的童鞋自行在下方链接下载:

15320
来自专栏IT开发技术与工作效率

正则表达式优化

DFA (Deterministic Finite Automaton 确定有穷自动机): 常见的只有MySQL,文本主导,不支持反向引用和捕获括号,但快

12010
来自专栏Zack说码

你真的完全了解Java动态代理吗?看这篇就够了

之前讲了《零基础带你看Spring源码——IOC控制反转》,本来打算下一篇讲讲Srping的AOP的,但是其中会涉及到Java的动态代理,所以先单独一篇来了解下...

10930
来自专栏Java学习录

SpringIOC源码解析(下)

本篇文章是SpringIOC源码解析(上)的续集,上一篇文章介绍了使用XML的方式启动Spring,然后追踪了BeanFactory容器的创建、配置文件的解析、...

10630
来自专栏数据分析1480

大数据之脚踏实地学01--虚拟机和Linux系统的安装

曾记得我在读研的时候,参加了中国统计年会(2013年),在会上很多领域内的专家都谈及了大数据一词,然而那个时候的我并没有那么敏感。短短5年过去了,大数据行业发展...

17020
来自专栏方丈的寺院

Mongo连接分析

在前面的文章中有分析过关系型数据库的连接,以及连接池的原理。在mongo数据库同样存在,经常看到有网友在问mongo 连接了数据库要不要关,怎么关。内置的数据库...

13420
来自专栏数据分析1480

学习大数据要掌握哪些语言?需要学习哪些内容?

大数据是近五年兴起的行业,发展迅速,很多技术经过这些年的迭代也变得比较成熟了,同时新的东西也不断涌现,想要保持自己竞争力的唯一办法就是不断学习。但是,大数据需要...

7320
来自专栏Java编程指南

作为一名程序员,谁没跳过槽,“6”招让你“空降”大厂

转载自:https://blog.csdn.net/Java__xiaoze/article/details/96878759

8930

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励