JVM 如何打破双亲委派模型?

虽然双亲委派模型是 Java 类加载机制的推荐实现方式,但在某些情况下,为了实现特定的功能,可能需要打破双亲委派模型。以下是一些常见的打破双亲委派模型的方法和场景:

1. 重写 loadClass 方法 (不推荐):

  • 原理: java.lang.ClassLoaderloadClass 方法实现了双亲委派模型的逻辑。默认情况下,loadClass 方法会先检查类是否已经被加载过,如果没有,则委托给父类加载器加载。如果父类加载器无法加载,则调用 findClass 方法尝试自己加载。

  • 打破方式: 重写 loadClass 方法,不遵循双亲委派模型的逻辑,而是直接调用 findClass 方法尝试自己加载类,或者自定义加载逻辑。

  • 示例:

    public class MyClassLoader extends ClassLoader {@Overridepublic Class<?> loadClass(String name) throws ClassNotFoundException {// 不再委托给父类加载器,直接尝试自己加载return findClass(name); }@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {// 实现自定义的类加载逻辑// ...}
    }
    
  • 缺点:

    • 破坏了双亲委派模型的优点: 可能会导致类的重复加载、核心类库被篡改等问题。
    • 容易出错: 需要自己处理类加载的各种细节,容易出错。
    • 不推荐: 除非有非常特殊的需求,否则不建议重写 loadClass 方法。

2. 使用线程上下文类加载器 (Thread Context ClassLoader):

  • 原理:
    • 每个线程都有一个关联的上下文类加载器 (Context ClassLoader)。
    • 可以通过 Thread.currentThread().getContextClassLoader() 获取当前线程的上下文类加载器。
    • 可以通过 Thread.currentThread().setContextClassLoader(ClassLoader cl) 设置当前线程的上下文类加载器。
    • 如果没有设置,线程上下文类加载器默认是应用程序类加载器 (AppClassLoader)。
  • 打破方式:
    • 在需要打破双亲委派模型的地方,获取当前线程的上下文类加载器,并使用它来加载类。
    • 例如,JDBC 驱动程序通常由应用程序类加载器加载,但 JDBC API (如 java.sql.DriverManager) 需要能够加载这些驱动程序。DriverManager 会使用线程上下文类加载器来加载驱动程序。
  • 应用场景:
    • SPI (Service Provider Interface): Java 中的 SPI 机制(例如 JDBC、JNDI、JAXP 等)通常使用线程上下文类加载器来加载服务提供者的实现类。
    • 框架和容器: 一些框架和容器(例如,Tomcat、Spring)会使用线程上下文类加载器来加载应用程序的类或资源。
  • 示例:
       // 获取当前线程的上下文类加载器ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();// 使用上下文类加载器加载类try {Class<?> myClass = contextClassLoader.loadClass("com.example.MyClass");// ...} catch (ClassNotFoundException e) {// ...}

3. 自定义类加载器并重写 findClass 方法 (推荐):

  • 原理:
    • 继承 java.lang.ClassLoader,并重写 findClass 方法。
    • findClass 方法中实现自己的类加载逻辑,例如从特定的目录、URL 或数据库中加载类。
  • 优点:
    • 可以灵活地控制类的加载过程。
    • 可以实现一些特殊的功能,例如热部署、模块化等。
  • 示例: (前面已经提供过,此处不再重复)

4. OSGi (Open Service Gateway initiative):

  • 原理:
    • OSGi 是一个模块化系统,每个模块(bundle)都有自己的类加载器。
    • OSGi 的类加载器模型不是严格的双亲委派模型,而是更复杂的网状结构。
    • OSGi 允许模块显式地声明它们依赖的其他模块,以及它们导出的包。
    • OSGi 框架会根据这些声明来解析模块之间的依赖关系,并加载相应的类。
  • 打破方式: OSGi 的类加载器模型本身就不是双亲委派模型。

5. Tomcat 的类加载器:

  • 原理:
    • Tomcat 为了实现 Web 应用程序之间的隔离,以及共享库的加载,使用了多个类加载器。
    • Tomcat 的类加载器结构:
      • Bootstrap: 加载 JVM 启动所需的类。
      • System: 加载 Tomcat 自身的类。
      • Common: 加载 Tomcat 和所有 Web 应用程序都可以访问的类 (例如, JDBC 驱动)。
      • WebappX: 每个 Web 应用程序都有一个独立的 WebAppClassLoader,负责加载该应用程序的类 (位于 WEB-INF/classesWEB-INF/lib 目录下).
      • Shared: (可选) 存放所有web应用共享的类.
  • 加载顺序:
    1. Bootstrap
    2. System
    3. Common
    4. WebappX (先在 WEB-INF/classes 中查找, 再在 WEB-INF/lib 中查找,最后才委托给父类加载器).
    5. Shared (如果配置了的话)
  • 打破双亲委派:
    • WebAppClassLoader 会优先在自己的范围内查找类,而不是立即委托给父类加载器, 这打破了双亲委派模型。
    • 这样做的好处是:
      • 隔离性: 不同的 Web 应用程序可以使用不同版本的类库,而不会相互干扰。
      • 灵活性: Web 应用程序可以覆盖 Tomcat 或共享库提供的类。

总结:

打破双亲委派模型的主要方法有:

  • 重写 loadClass 方法 (不推荐)。
  • 使用线程上下文类加载器 (常用于 SPI 机制)。
  • 自定义类加载器并重写 findClass 方法 (推荐)。
  • OSGi 模块化系统 (使用自定义的类加载器模型)。
  • Tomcat 的类加载机制.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/899330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 大视界 -- 基于 Java 的大数据隐私计算在医疗影像数据共享中的实践探索(158)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

logstash收集数据

防止ES的的I/O的压力过大&#xff0c;使用redis/kafka进行缓冲。 对redis的要求 Redis input plugin | Logstash Reference [8.17] | Elastic 一般企业要求的架构 我实现的架构 filebeat把数据传给logstash 配置好filebeat把收集到的数据输入到redis 然后执行命令&#xff0…

使用ModbusRTU读取松下测高仪的高度

使用C#通过Modbus RTU读取松下测高仪高度 1. 准备工作 1.1 硬件连接 确保松下测高仪支持Modbus RTU协议(需查阅设备手册确认)。通过RS-485或RS-232接口连接设备与计算机,可能需要USB转串口适配器。确认通信参数(波特率、数据位、停止位、奇偶校验),常见设置为:9600波特…

详解Http:在QT中使用Http协议

目录 一、HTTP 概述 1、主要特点 2、HTTP 方法 3、HTTP 状态码 4、HTTP 头部 5、HTTP的工作原理 二、在Qt中使用HTTP 1、发送简单的HTTP请求 2、发送POST请求 3、处理异步请求 4、使用QSslConfiguration进行HTTPS 5、 处理JSON响应 6、处理错误 三、总结 一、HTTP…

MAXKB部署,使用和注意事项

MaxKB Max Knowledge Base&#xff0c;是一款基于大语言模型和 RAG 的开源知识库问答系统&#xff0c;广泛应用于智能客服、企业内部知识库、学术研究与教育等场景。作为一款专注于知识库问答场景的软件产品&#xff0c;MaxKB 能够为企业的智能化进程注入新的动力&#xff0c;…

刚刚整理实测可用的股票数据API接口集合推荐:同花顺、雅虎API、智兔数服、聚合数据等Python量化分析各项数据全面丰富

在金融科技高速发展的今天&#xff0c;股票API接口已成为开发者、量化交易者和金融从业者的核心工具之一。它通过标准化的数据接口&#xff0c;帮助用户快速获取实时或历史市场数据&#xff0c;为投资决策、策略回测和金融应用开发提供支持。本文将深入解析股票API的核心功能、…

C笔记20250325

一:宏常量 和 const常量的区别 宏常量 使用预处理器指令#define来定义。 #define PI 3.14159 没有类型信息&#xff0c;仅仅是简单的文本替换。这意味着编译器不会对宏进行类型检查&#xff0c;可能导致潜在的错误。宏不是变量&#xff0c;不占用内存空间。它只是在预处理阶…

docker - compose up - d`命令解释,重复运行会覆盖原有容器吗

docker - compose up - d`命令解释,重复运行会覆盖原有容器吗 docker - compose up - d 是一个用于管理 Docker 容器的命令,具体含义如下: 命令含义: up:用于创建、启动并运行容器,会根据 docker - compose.yml 文件中定义的服务配置来操作。-d:表示以“分离模式”(det…

03-SpringBoot3入门-配置文件(自定义配置及读取)

1、自定义配置 # 自定义配置 zbj:user:username: rootpassword: 123456# 自定义集合gfs:- a- b- c2、读取 1&#xff09;User类 package com.sgu.pojo;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.spring…

【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置

噩梦终结&#xff1a;Flutter 配安卓、鸿蒙、iOS 真机调试环境 问题背景 很多开发者在配置 Flutter 项目环境时遇到困难&#xff0c;尤其是在处理 Android、鸿蒙和 iOS 真机调试环境时。卓伊凡最近接手了一个项目&#xff0c;发现很多“专业程序员”在环境搭建上花费了大量时…

进程状态:Linux的幕后指挥管理,穿越操作系统进程的静与动

文章目录 引言&#xff1a;进程的生命与状态&#xff1a;动与静的交响曲一、操作系统中的进程状态概述1.1 经典的进程状态模型1.2 进程状态转换图 二、Linux操作系统中的进程状态2.1 Linux进程状态的分类2.2 各状态的详细解释 2.3 Linux进程状态表2.4 使用ps查看进程状态三、进…

MOSN(Modular Open Smart Network)-05-MOSN 平滑升级原理解析

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFAStack-00-sofa 技术栈概览 MOSN&#xff08;Modular O…

基于深度学习的图像超分辨率技术研究与实现

一、引言 在数字图像处理领域&#xff0c;图像超分辨率技术一直是一个备受关注的热点话题。随着人们对图像质量要求的不断提高&#xff0c;如何将低分辨率图像提升到高分辨率&#xff0c;同时保持图像的细节和清晰度&#xff0c;成为了一个极具挑战性的问题。传统的图像超分辨率…

构建高可用性西门子Camstar服务守护者:异常监控与自愈实践

在智能制造领域,西门子Camstar作为领先的MES系统承载着关键生产业务。但在实际运维中,我们发现其服务常因数据库负载激增(如SQL阻塞链超时)或应用服务器资源耗尽(CPU峰值达90%以上)导致服务不可用。传统人工干预方式平均故障恢复时间长达47分钟,这对连续生产场景构成了严…

Java Collection API增强功能系列之二 List.of、Set.of、Map.of

Java 9集合工厂方法&#xff1a;用List.of、Set.of、Map.of创建安全不可变集合 Java 9引入了革命性的集合工厂方法List.of、Set.of和Map.of&#xff0c;彻底改变了开发者创建小型不可变集合的方式。这些方法不仅语法简洁&#xff0c;还在安全性和性能上实现了质的飞跃。本文将…

网络通信微服务

网络通信 VPN 服务器分配内网 IP&#xff0c;加密所有流量,以使用外网访问内网资源 使用了VPN只是第一关&#xff0c;只进入了人家的大厅&#xff0c;只可以访问公共服务&#xff08;像是只可以在人间公司的大厅里溜达&#xff09;&#xff0c;若想要访问人家提供的高级服务&a…

arm之s3c2440的I2C的用法

基础概念 IC&#xff08;Inter-Integrated Circuit&#xff09;又称I2C&#xff0c;是是IICBus简称&#xff0c;所以中文应该叫集成电路总线。 IIC的总线的使用场景&#xff0c;所有挂载在IIC总线上的设备都有两根信号线&#xff0c;一根是数据线SDA&#xff0c;另一 根是时钟…

算法 | 蜣螂优化算法原理,引言,公式,算法改进综述,应用场景及matlab完整代码

蜣螂优化算法(Dung Beetle Optimizer, DBO)详解 1. 算法原理 蜣螂优化算法(DBO)是一种基于自然界蜣螂行为的元启发式优化算法,灵感来源于蜣螂的滚球、繁殖、觅食和偷窃行为。其核心思想是通过模拟蜣螂在复杂环境中的协作与竞争机制,解决全局优化问题。关键行为模拟: 滚球…

uniapp开发实战自定义组件形式实现自定义海报功能

在 UniApp 中实现自定义海报功能,可以通过 Canvas 来绘制海报。Canvas 提供了丰富的绘图 API,可以精确控制文字、图片和二维码的位置。下面是一个完整的示例,展示如何创建一个自定义海报组件。 项目结构 假设你的项目结构如下: project-root/ ├── pages/ │ └──…

dockerfile构建镜像方式

在 Docker 中&#xff0c;可使用 docker build 命令依据 Dockerfile 构建镜像。下面为你详细介绍构建镜像的具体方式。 基本构建命令 若要构建镜像&#xff0c;需在包含 Dockerfile 的目录下执行 docker build 命令。基本语法如下&#xff1a; bash docker build -t <镜像…