首页 > 其他分享 >如何打破双亲委派机制

如何打破双亲委派机制

时间:2024-10-13 23:47:27浏览次数:8  
标签:委派 loadClass 打破 JNDI 双亲 方法 加载

双亲委派底层运行过程

双亲委派模型对于保证Java程序的稳定运作很重要,但它的实现却非常简单,实现双亲委派的代码都集中在 java.lang.ClassLoader的loadClass()方法之中,代码简单,逻辑清晰易懂:先检查类是否已经被加载过,若没有加载则调用父加载器的loadClass0方法,若父加载器为空则默认使用启动类加载器作为父加载器。如果父类加载失败,抛出ClassNotFoundException异常后,再调用自己的findClass0)方法进行加载。

双亲委派模型主要是由ClassLoader#loadClass实现的,我们只需要自定义类加载器,并且重写其中的 loadClass方法,即可破坏双亲委派模型。
 

打破双亲委派机制有三种方法

本质上只有第一种算是真正的打破了双亲委派机制:

自定义类加载器并且重写loadClass方法。Tomcat通过这种方式实现应用之间类隔离,《面试篇》中分享它的做法。

线程上下文类加载器。利用上下文类加载器加载类,比如JDBC和JNDI等。

Osgi框架的类加载器。历史上Osgi框架实现了一套新的类加载器机制,允许同级之间委托进行类的加载,目前很少使用。

打破双亲委派的例子

向前兼容

由于双亲委派模型是在JDK1.2之后才被引入的,而类加载器和抽象类java.lang.ClassLoader则是JDK1.0时候就已经存在,面对已经存在的用户自定义类加载器的实现代码,Java设计者引入双亲委派模型时不得不做出一些妥协。

为了向前兼容,JDK1.2之后的java.lang.ClassLoader添加了一个新的proceted方法findClass(),在此之前,用户去继承java.lang.ClassLoader的唯一目的就是重写loadClass(方法,因为虚拟机在进行类加载的时候会调用加载器的私有方法loadClassInternal(),而这个方法的唯一逻辑就是去调用自己的loadClass()。

JDK1.2之后已不再提倡用户再去覆盖loadClass0方法,应当把自己的类加载逻辑写到findClass(方法中,在 loadClass()方法的逻辑里,如果父类加载器加载失败,则会调用自己的findClass(方法来完成加载,这样就可以保证新写出来的类加载器是符合双亲委派模型的。

SPI实现

双亲委派模型很好地解决了各个类加载器的基础类统一问题(越基础的类由越上层的加载器进行加载),基础类之所以被称为“基础”,是因为它们总是作为被调用的API。但是,如果基础类又要调用用户的代码,那该怎么办呢。

这并非是不可能的事情,一个典型的例子便是JNDI服务,它的代码由启动类加载器去加载(在JDK1.3时放进
rt.jar),但JNDI的目的就是对资源进行集中管理和查找,它需要调用独立厂商实现部部署在应用程序的classpath下的JNDI接口提供者(SPI,Service Provider Interface)的代码,但启动类加载器不可能“认识”这些代码。

为了解决这个困境,Java设计团队只好引入了一个不太优雅的设计:线程上下文类加载器(Thread Context ClassLoader)。这个类加载器可以通过java.lang.Thread类的setContextClassLoader(方法进行设置,如果创建线程时还未设置,它将会从父线程中继承一个;如果在应用程序的全局范围内都没有设置过,那么这个类加载器默认就是应用程序类加载器。

有了线程上下文类加载器,JNDI服务使用这个线程上下文类加载器去加载所需要的SPI代码,也就是父类加载器请求子类加载器去完成类加载动作,这种行为实际上就是打坡了双亲委派模型的层次结构来逆向使用类加载器,已经违背了双亲委派模型,但这也是无可奈何的事情。

Java中所有涉及SPI的加载动作基本上都采用这种方式,例如JNDI,JDBC,JCE,JAXB和JBI等。

标签:委派,loadClass,打破,JNDI,双亲,方法,加载
From: https://blog.csdn.net/sdg_advance/article/details/142835057

相关文章

  • 企业竞争情报实时获取,驱动企业打破市场桎梏
    近年来,国内的市场环境一直在高速变化,多方因素的影响下,加速了市场环境的变化,大部分行业迎来发展拐点,行业产能过剩,市场竞争激烈,业务增长困难。房地产行业在我国城镇化背景下,经历了近20年的高速发展,近年来受政策收紧和其他因素影响,市场需求萎缩,增量困难;医药行业市场需求持续释放,政策红......
  • IntelliJ IDEA远程开发:释放本地设备,打破资源与环境的限制
    文章目录IntelliJIDEA远程开发:释放本地设备,打破资源与环境的限制应用场景远程开发优势如何实现远程开发进入远程开发`RemoteDevelopment`选择远程开发方式配置SSH代理转发通过`DevContainer`创建开发容器公众号,感谢!IntelliJIDEA远程开发:释放本地设备,打破资源与环境的限......
  • SAP BTP助力企业打破数据孤岛
    在当今数字化时代,企业面临着海量数据的管理与利用挑战,其中数据孤岛现象成为制约企业发展的重要因素。数据孤岛是指企业内海量的数据由于组织战略、架构设置、数字化建设等原因,分散存储在组织的各个部门、业务系统、应用之中,彼此无法互联互通、共享,也无法被有效利用,形成了一个又一个......
  • 从数据中台到数据飞轮:打破孤岛,实现数据的连续演进
    在数字化的浪潮中,企业对数据的依赖日益增加,数据中台已经成为众多企业构建数据能力的基石。然而,光有一个功能全面的数据中台并不足以使企业的数据价值最大化,这一点在业界已经逐渐形成共识。进一步地,数据飞轮的概念应运而生,被视作是超越数据中台,实现数据动能循环和业务增长的关键阶段......
  • JVM —— 类加载器的分类,双亲委派机制
    文章目录一、类加载器的分类【理解】1.1概述1.2JDK8及之前的版本1.2.1启动类加载器1.2.2扩展类加载器和应用程序类加载器扩展类加载器应用程序类加载器1.3JDK9之后的类加载器1.4ClassLoader中的两个方法【应用】二、双亲委派模型【理解】2.1什么是双亲委派机制面试题:类的双......
  • JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
    文章目录一、类加载器1.1什么是类加载器、类加载器作用1.2应用场景1.3类加载时机1.4类加载器分类1.4.1概述1.4.2JDK8及之前的版本1.4.3JDK9之后的类加载器二、双亲委派模型2.1什么是双亲委派模型2.2JVM为什么采用双亲委派机制2.3打破双亲委派机制2.4总结三......
  • Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局
     作者|海野AI圈子的红人,AI大神AndrejKarpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为EurekaLabs的人工智能+教育公司 ,宣布将长期致力于AI原生教育。近日,AndrejKarpathy接受了NoPriors(投资博客)的采访,与硅谷知名投资人SaraGuo和EladG......
  • 《 C++ 修炼全景指南:九 》打破编程瓶颈!掌握二叉搜索树的高效实现与技巧
    摘要本文详细探讨了二叉搜索树(BinarySearchTree,BST)的核心概念和技术细节,包括插入、查找、删除、遍历等基本操作,并结合实际代码演示了如何实现这些功能。文章深入分析了二叉搜索树的性能优势及其时间复杂度,同时介绍了前驱、后继的查找方法等高级功能。通过自定义实现的......
  • 什么是 Rainbond?打破 Kubernetes 的复杂性
    近年来,随着云原生技术的快速发展,Kubernetes已经成为容器编排的标准。然而,尽管Kubernetes功能强大,它的复杂性也成为了众多开发者和运维人员的一大挑战。对于那些希望专注于应用开发的团队来说,学习和管理Kubernetes可能是一个高昂的学习成本,尤其是在中小企业中,开发者并没有足够......
  • Tomcat双亲委派机制
    什么是类加载机制?代码编译的结果从本地机器码转变成字节码,是存储格式的一小步,却是编程语言发展的一大步。Java虚拟机把描述类的数据从Class文件加载进内存,并对数据进行校验,转换解析和初始化,最终形成可以呗虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。虚拟机设计团队......