java-如何打破双亲委派机制

在Java虚拟机(JVM)中,双亲委派模型是一种类加载器之间的层次模型,它定义了类加载的规则,即当一个类需要被加载时,JVM默认的行为是首先请求父类加载器加载该类,只有当父类加载器无法加载该类时,才由自己来加载。这种模型确保了类的唯一性和安全性。然而,在某些特定场景下,可能需要打破双亲委派模型,以实现更灵活的类加载机制。以下是如何打破双亲委派模型的详细解释。
### 为什么需要打破双亲委派模型
1. **SPI(Service Provider Interface)**:Java的SPI机制允许第三方为接口提供实现,而这些实现类通常是由不同的类加载器加载的,如果坚持双亲委派模型,将无法加载这些实现类。
2. **代码热部署**:在运行时需要替换或者更新某些类,而无需重启整个应用,这就需要自定义类加载器来加载新的类。
3. **同一个类的不同版本**:在某些情况下,可能需要同时运行同一个类的不同版本,双亲委派模型无法满足这种需求。
### 如何打破双亲委派模型
打破双亲委派模型通常涉及自定义类加载器,以下是实现这一目标的方法:
#### 1. 继承`java.lang.ClassLoader`
要打破双亲委派模型,首先需要自定义类加载器,通过继承`java.lang.ClassLoader`类并重写其`findClass`方法,可以自定义类的加载逻辑。
```java
public class CustomClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 自定义类加载逻辑
        byte[] classData = loadClassData(name);
        if (classData == null) {
            throw new ClassNotFoundException(name);
        }
        return defineClass(name, classData, 0, classData.length);
    }
    private byte[] loadClassData(String name) {
        // 从文件系统、数据库或其他源读取类文件的数据
    }
}
```
#### 2. 重写`loadClass`方法
为了完全打破双亲委派模型,可以重写`ClassLoader`的`loadClass`方法。这个方法负责实现双亲委派逻辑,如果重写它,就可以绕过双亲委派机制。
```java
public class CustomClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // 自定义加载逻辑,不委派给父类加载器
        return findClass(name);
    }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 自定义类加载逻辑
        byte[] classData = loadClassData(name);
        if (classData == null) {
            throw new ClassNotFoundException(name);
        }
        return defineClass(name, classData, 0, classData.length);
    }
    private byte[] loadClassData(String name) {
        // 从文件系统、数据库或其他源读取类文件的数据
    }
}
```
#### 3. 使用线程上下文类加载器
Java提供了线程上下文类加载器(Thread Context ClassLoader),它允许开发者在运行期动态地覆盖默认的类加载器。通过设置线程的上下文类加载器,可以实现类加载器的动态切换。
```java
Thread.currentThread().setContextClassLoader(new CustomClassLoader());
```
#### 4. 实现SPI的类加载器
对于SPI的实现类,通常会使用一种特殊的类加载器,比如Java SPI中的`java.util.ServiceLoader`,它使用线程上下文类加载器来加载服务提供者。
```java
ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class, Thread.currentThread().getContextClassLoader());
```
### 注意事项
打破双亲委派模型虽然提供了灵活性,但也带来了一些潜在的风险和需要注意的问题:
- **类唯一性**:同一个类可以被不同的类加载器加载,这可能导致类型转换异常或者单例模式失效。
- **安全性**:自定义类加载器可能会加载不可信的代码,增加了安全风险。
- **兼容性**:不同类加载器加载的类可能存在版本不兼容的问题。
### 实际应用案例
以下是一些实际应用中打破双亲委派模型的场景:
- **OSGi框架**:它允许同一个JVM中运行多个版本的Java库,每个bundle都有自己的类加载器。
- **Tomcat容器**:为了实现Web应用的热部署,Tomcat为每个Web应用创建了一个独立的类加载器。
- **JDBC驱动加载**:JDBC驱动通常是通过SPI机制加载的,使用线程上下文类加载器来加载驱动类。
### 总结
打破双亲委派模型是一种高级的类加载器使用技巧,它为Java应用程序提供了更大的灵活性和扩展性。通过自定义类加载器,可以实现在
 

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

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

相关文章

【BUG】已解决:error: legacy - install - failure

error: legacy - install - failure 目录 error: legacy - install - failure 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&…

51单片机14(独立按键实验)

一、按键介绍 1、按键是一种电子开关&#xff0c;使用的时候&#xff0c;只要轻轻的按下我们的这个按钮&#xff0c;按钮就可以使这个开关导通。 2、当松开这个手的时候&#xff0c;我们的这个开关&#xff0c;就断开开发板上使用的这个按键&#xff0c;它的内部结构&#xff…

免费分享:2021年度全国城乡划分代码(附下载方法)

《关于统计上划分城乡的规定》指出&#xff1a;“本规定作为统计上划分城乡的依据&#xff0c;不改变现有的行政区划、隶属关系、管理权限和机构编制&#xff0c;以及土地规划、城乡规划等有关规定”。统计用区划代码和城乡划分代码用于统计工作&#xff0c;需要在其他工作中使…

Transforms

深度学习中的Transforms 概述 Transforms在深度学习中起到了关键的作用&#xff0c;主要用于数据预处理、特征提取和数据增强&#xff08;Data Augmentation&#xff09;。通过对数据进行各种变换&#xff0c;能够提升模型的训练效果和泛化能力。 数据增强&#xff08;Data …

回溯题目的套路总结

前言 昨天写完了LeeCode的7&#xff0c;8道回溯算法的题目&#xff0c;写一下总结&#xff0c;这类题目的共同特点就是暴力搜索问题&#xff0c;排列组合或者递归&#xff0c;枚举出所有可能的答案&#xff0c;思路很简单&#xff0c;实现起来的套路也很通用&#xff0c;一…

java题目之抽奖以及优化方式

public class Main9 {public static void main(String[] args) {int[]arr{ 2,588,888,1000,10000};int [] newArrnew int[arr.length];//3.抽奖Random rnew Random();//因为有5个奖项,所以这里循环五次for (int i 0; i <5 ; ) {//获取随机索引int randomIndexr.nextInt(arr…

前端-模拟请求数据mook第三方插件 json-server的使用

大纲 第一步下载第二配置mook的数据源第三配置启动命令第四运行模拟服务第五测试接口如果要进行更复杂的操作 第一步下载 npm install json-server -D"devDependencies": {"json-server": "^1.0.0-beta.1"}第二配置mook的数据源 在项目的根目录…

图纸为什么需要加密?2024超好用的图纸加密软件推荐

图纸通常包含产品的设计细节、规格和技术信息&#xff0c;这些都是公司的核心知识产权。加密可以防止未经授权的访问和复制&#xff0c;避免知识产权被盗用或侵权。 图纸加密软件对于保护企业的知识产权和商业秘密至关重要&#xff0c;特别是在CAD&#xff08;计算机辅助设计&…

内网安全:各类密码的抓取

Mimikatz在线读取SAM文件 离线读取SAM文件 在线读取lsass进程 离线读取lsass进程 BrowserGhost浏览器密码抓取 Sharp-HackBrowserData浏览器密码抓取 SharpDecryptPwd数据库密码抓取 LaZagne各类密码的抓取 Windows其他类型抓NTLM Hash工具 sam文件和lsass进程就是Wind…

员工的成长=公司潜力的发展,最大的误区99.99%机器视觉公司不培训员工

员工成才最好的方式&#xff0c;绝对是培训。 机器视觉公司培训99.99%从来不培训员工的&#xff0c;不训练员工。 员工不变得优秀&#xff0c;如何更好的服务客户&#xff0c;无法搞定客户。 去和客户商务谈判&#xff0c;让自己员工去送死&#xff0c; 不去学习如何搞定客户&a…

谷粒商城-商品上架

1.sku在es中的存储模型分析(spring整和es) es中所有数据存在内存中,内存产品贵,能节省就节省,只保存有用的信息 两种保存方法:(空间换时间,时间换空间): 我们选空间换时间 ES中放这些东西: "mappings": { "properties": { "skuId"…

【C++】deque以及优先级队列

容器适配器 deque的介绍deque的原理介绍 priority_queue的介绍与使用priority_queue的介绍priority_queue的使用constructor&#xff08;构造函数&#xff09;emptypushpoptopsize priority_queue的模拟实现 仿函数何为适配器容器适配器deque的缺陷选择deque作为适配器的理由ST…

使用element UI Cascader 级联选择器实现省/市/区选择

<template><div><label>位置</label><el-cascader:options"pcaTextArr"v-model"selectedOptions"change"handleChangeAddress":props"{expandTrigger: hover,multiple: true,checkStrictly: true,emitPath: fal…

mailcow搭建安装教程:如何搭建专属邮箱!

mailcow搭建安装教程怎么用&#xff1f;怎么有效搭建邮箱服务器&#xff1f; 随着电子邮件在工作和生活中的重要性日益增加&#xff0c;拥有一个专属的电子邮件服务器变得越来越有吸引力。AokSend将详细介绍如何通过mailcow搭建一个专属邮箱&#xff0c;为你提供全方位的邮件管…

看起来很炫酷的科技感登录页面模板HTML

代码下载地址&#xff1a; 炫酷科技感登录页面模板带动画 (bootstrapmb.com)https://www.bootstrapmb.com/item/11891

Mailspring搭建安装教程:打造个性邮件体验

Mailspring搭建安装教程步骤&#xff01;如何选择电子邮件服务商&#xff1f; Mailspring作为一款功能强大、界面友好的邮件客户端&#xff0c;成为了许多用户的首选。AokSend将为大家提供详细的Mailspring搭建安装教程&#xff0c;帮助您打造个性化的邮件体验。 Mailspring搭…

Mybatis<collection>实现一对多

时隔多年又用到这样的查询方式了,提前声明一下分页最后返回的数据会小于每页条数&#xff0c;废话不多说直接上代码&#xff01; Data public class PbcUserTargetTaskPageVO {ApiModelProperty("个人绩效指标id")private Long id;ApiModelProperty("月份"…

vue2与vue3使用emit传值,v-model和.sync的区别

一、v-model和.sync的区别 我们下面的例子只有一个双向绑定值其实是可以使用input的 .sync与v-model区别是 相同点&#xff1a;都是语法糖&#xff0c;都可以实现父子组件中的数据的双向通信。 区别点&#xff1a;格式不同。 v-model"num" v-model&#xff1a; …

【Golang 面试基础题】每日 5 题(二)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

uniapp判断h5/微信小程序/app端+实战展示

文章目录 导文使用条件编译的基本语法常见的平台标识符示例实战展示使用场景举例注意事项 导文 这里是导文 当你在开发Uni-app时&#xff0c;需要根据不同的平台&#xff08;比如App端、H5端、微信小程序等&#xff09;来执行不同的代码逻辑&#xff0c;可以使用条件编译来实现…