JVM 如何打破双亲委派模型?
虽然双亲委派模型是 Java 类加载机制的推荐实现方式,但在某些情况下,为了实现特定的功能,可能需要打破双亲委派模型。以下是一些常见的打破双亲委派模型的方法和场景:
1. 重写 loadClass 方法 (不推荐):
-
原理:
java.lang.ClassLoader的loadClass方法实现了双亲委派模型的逻辑。默认情况下,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/classes和WEB-INF/lib目录下).Shared: (可选) 存放所有web应用共享的类.
- 加载顺序:
BootstrapSystemCommonWebappX(先在WEB-INF/classes中查找, 再在WEB-INF/lib中查找,最后才委托给父类加载器).Shared(如果配置了的话)
- 打破双亲委派:
WebAppClassLoader会优先在自己的范围内查找类,而不是立即委托给父类加载器, 这打破了双亲委派模型。- 这样做的好处是:
- 隔离性: 不同的 Web 应用程序可以使用不同版本的类库,而不会相互干扰。
- 灵活性: Web 应用程序可以覆盖 Tomcat 或共享库提供的类。
总结:
打破双亲委派模型的主要方法有:
- 重写
loadClass方法 (不推荐)。 - 使用线程上下文类加载器 (常用于 SPI 机制)。
- 自定义类加载器并重写
findClass方法 (推荐)。 - OSGi 模块化系统 (使用自定义的类加载器模型)。
- Tomcat 的类加载机制.
相关文章:
JVM 如何打破双亲委派模型?
虽然双亲委派模型是 Java 类加载机制的推荐实现方式,但在某些情况下,为了实现特定的功能,可能需要打破双亲委派模型。以下是一些常见的打破双亲委派模型的方法和场景: 1. 重写 loadClass 方法 (不推荐): 原理: java.l…...
DeepSeek结合MCP Server与Cursor,实现服务器资源的自动化管理
MCP Server是最近AI圈子中又一个新的热门话题。很多用户都通过结合大语言模型、MCP Server,实现了一些工具流的自动化,例如,你只需要给出文字指令,就可以让Blender自动化完成建模的工作。你有没有想过,利用MCP来让AI A…...
SpringAI与JBoltAI深度对比:从工具集到企业级AI开发范式的跃迁
一、Java生态下大模型开发的困境与需求 技术公司的能力断层 多数企业缺乏将Java与大模型结合的标准开发范式,停留在碎片化工具使用阶段。 大模型应用需要全生命周期管理能力,而不仅仅是API调用。 工具集的局限性 SpringAI作为工具集的定位࿱…...
后端返回了 xlsx 文件流,前端怎么下载处理
当后端返回一个 .xlsx 文件流时,前端可以通过 JavaScript 处理这个文件流并触发浏览器下载。 实现步骤 发送请求获取文件流: 使用 fetch 或 axios 等工具向后端发送请求,确保响应类型设置为 blob(二进制数据流)。 创建…...
一文读懂Python之json模块(33)
一、json模块介绍 json模块的功能是将序列化的json数据从文件里读取出来或者存入文件。json是一种轻量级的数据交换格式,在大部分语言中,它被理解为数组(array)。 json模块序列化与反序列化的过程分别是 encoding和 decoding。e…...
Python中multiprocessing的使用详解
1.实现多进程 代码实现: from multiprocessing import Process import datetime import timedef task01(name):current_timedatetime.datetime.now()start_timecurrent_time.strftime(%Y-%m-%d %H:%M:%S). "{:03d}".format(current_time.microsecond //…...
强化学习与神经网络结合(以 DQN 展开)
目录 基于 PyTorch 实现简单 DQN double DQN dueling DQN Noisy DQN:通过噪声层实现探索,替代 ε- 贪心策略 Rainbow_DQN如何计算连续型的Actions 强化学习中,智能体(Agent)通过与环境交互学习最优策略。当状态空间或动…...
函数式组件中的渲染函数 JSX
在 Vue.js 和 React 等现代前端框架中,函数式组件已成为一种非常流行的设计模式。函数式组件是一种没有内部状态和生命周期方法的组件,其主要功能是接受 props 并渲染 UI。随着这些框架的演进,渲染函数和 JSX(JavaScript XML&…...
北斗导航 | 基于因子图优化的GNSS/INS组合导航完好性监测算法研究,附matlab代码
以下是一篇基于因子图优化(FGO)的GNSS/INS组合导航完好性监测算法的论文框架及核心内容,包含数学模型、完整Matlab代码及仿真分析基于因子图优化的GNSS/INS组合导航完好性监测算法研究 摘要 针对传统卡尔曼滤波在组合导航完好性监测中对非线性与非高斯噪声敏感的问题,本文…...
飞书电子表格自建应用
背景 coze官方的插件不支持更多的飞书电子表格操作,因为需要自建应用 飞书创建文件夹 创建应用 开发者后台 - 飞书开放平台 添加机器人 添加权限 创建群 添加刚刚创建的机器人到群里 文件夹邀请群 创建好后,就可以拿到id和key 参考教程: 创…...
深度学习四大核心架构:神经网络(NN)、卷积神经网络(CNN)、循环神经网络(RNN)与Transformer全概述
目录 📂 深度学习四大核心架构 🌰 知识点概述 🧠 核心区别对比表 ⚡ 生活化案例理解 🔑 选型指南 📂 深度学习四大核心架构 第一篇: 神经网络基础(NN) 🌰 知识点概述…...
MCP Server 实现一个 天气查询
Step1. 环境配置 安装 uv curl -LsSf https://astral.sh/uv/install.sh | shQuestion: 什么是 uv 呢和 conda 比有什么区别? Answer: 一个用 Rust 编写的超快速 (100x) Python 包管理器和环境管理工具,由 Astral 开发。定位为 pip 和 venv 的替代品…...
《强化学习基础概念:四大模型与两大损失》
强化学习基础概念一、策略模型1. 策略的定义2. 策略的作用3.策略模型 二、价值模型1. 价值函数的定义(1)状态值函数(State Value Function)(2)动作值函数(Action Value Function) 2.…...
Headless Chrome 优化:减少内存占用与提速技巧
在当今数据驱动的时代,爬虫技术在各行各业扮演着重要角色。传统的爬虫方法往往因为界面渲染和资源消耗过高而无法满足大规模数据采集的需求。本文将深度剖析 Headless Chrome 的优化方案,重点探讨如何利用代理 IP、Cookie 和 User-Agent 设置实现内存占用…...
知识就是力量——HELLO GAME WORD!
你好!游戏世界! 简介环境配置前期准备好文章介绍创建头像小功能组件安装本地中文字库HSV颜色空间音频生成空白的音频 游戏UI开发加载动画注册登录界面UI界面第一版第二版 第一个游戏(贪吃蛇)第二个游戏(俄罗斯方块&…...
电脑连不上手机热点会出现的小bug
一、问题展示 注意: 不要打开 隐藏热点 否则他就会在电脑上 找不到自己的热点 二、解决办法 把隐藏热点打开即可...
unity 做一个圆形分比图
// 在其他脚本中控制多段进度 using System.Collections.Generic; using UnityEngine;public class GameManager : MonoBehaviour {public MultiCircleProgress circleProgress;void Start(){// 初始化数据circleProgress.segments new List<MultiCircleProgress.ProgressS…...
JAVA反序列化深入学习(八):CommonsCollections6
与CC5相似: 在 CC5 中使用了 TiedMapEntry#toString 来触发 LazyMap#get在 CC6 中是通过 TiedMapEntry#hashCode 来触发 LazyMap#get 之前看到了 hashcode 方法也会调用 getValue() 方法然后调用到其中 map 的 get 方法触发 LazyMap,那重点就在于如何在反…...
鸿蒙项目源码-外卖点餐-原创!原创!原创!
鸿蒙外卖点餐外卖平台项目源码含文档包运行成功ArkTS语言。 我半个月写的原创作品,请尊重原创。 原创作品,盗版必究!!! 原创作品,盗版必究!!! 原创作品,盗版…...
计算机二级WPS Office第十一套WPS演示
解题过程...
React程序打包与部署
===================== 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 为生产环境准备React应用最小化和打包环境变量错误处理部署到托管服务部署到Netlify探索高级主题:Hooks、Su…...
ubuntu 创建新用户
给实验室服务器建用户,会担心除了基本的用户创建以外有没有别的没考虑到的。问了一下似乎没有,就按最基础的来就可以 # linux 自带的基础命令 # 创建用户,指定 home,设置 owner,设置密码 sudo useradd -d /home/abc a…...
代码随想录刷题day53|(二叉树篇)106.从中序与后序遍历序列构造二叉树(▲
目录 一、二叉树理论知识 二、构造二叉树思路 2.1 构造二叉树流程(给定中序后序 2.2 整体步骤 2.3 递归思路 2.4 给定前序和后序 三、相关算法题目 四、易错点 一、二叉树理论知识 详见:代码随想录刷题day34|(二叉树篇)二…...
Leetcode算法方法总结
1. 双指针法解决链表/数组题目 只要数组有序,就要想到双指针做法。还有二分法 回文串一般也会用到双指针,回文串的长度由于可能是奇数也可能是偶数,所以在寻找时,既需要寻找奇数长度的回文串,也需要寻找偶数长度的回文…...
全包圆玛奇朵样板间亮相,极简咖啡风引领家装新潮流
在追求品质生活的当下,家居装修风格的选择成为了许多消费者关注的焦点。近日,全包圆家居装饰有限公司精心打造的玛奇朵样板间正式对外开放,以其独特的咖啡色系极简风格,为家装市场带来了一股清新的潮流。玛奇朵样板间不仅展示了全…...
小红书多账号运营:如何实现每个账号独立 IP发布文章
一、多账号管理与 IP 隔离方案 1.电脑端实现:推荐使用指纹浏览器工具,为每个账号生成独立设备指纹(模拟不同 MAC 地址、内存等信息),并搭配兔子ip代理等服务商的 SOCKS5 代理,实现一机多开且每个账号独立 …...
大数据学习(92)-spark详解
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...
免费下载 | 2025年网络安全报告
报告总结了2024年的网络安全态势,并对2025年的安全趋势进行了预测和分析。报告涵盖了勒索软件、信息窃取软件、云安全、物联网设备安全等多个领域的安全事件和趋势,并提供了安全建议和最佳实践。 一、报告背景与目的 主题:2024企业信息安全峰…...
《Android低内存设备性能优化实战:深度解析Dalvik虚拟机参数调优》
1. 痛点分析:低内存设备的性能困局 现象描述:大应用运行时频繁GC导致卡顿 根本原因:Dalvik默认内存参数与硬件资源不匹配 解决方向:动态调整堆内存参数以平衡性能与资源消耗 2. 核心调优参数全景解析 关键参数矩阵࿱…...
RCE--解法
目录 一、利用php伪协议 1.代码分析 2.过程 3.结果 编辑 4.防御手段 二、RCE(php中点的构造) 1.代码分析 2.过程 一、利用php伪协议 <?php error_reporting(0); if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag|system|php|cat|sort…...
