当前位置: 首页 > news >正文

java双亲委派

类加载的过程

加载-》连接-》初始化

Image text

三种类加载器

AppClassLoader-> ExtClassLoader-> BootStrapClassLoader

  • 启动类加载器(Bootstrap ClassLoader)

jre/lib/*jar、rt.jar、jce.jar

  • 扩展类加载器(Extension ClassLoader)

jre/lib/ext/*.jar

  • 应用程序类加载器(Application ClassLoader)

classpath

demo

package com.jysemel.java.basic.claasloader;public class ClassLoaderDemo {public static void main(String[] args) {//父子关系 AppClassLoader-> ExtClassLoader-> BootStrapClassLoaderClassLoader demo  = ClassLoaderDemo.class.getClassLoader();System.out.println("demo " + demo);System.out.println("demo parent " + demo.getParent());//BootStrapClassLoader 引导类加载器,由C++ 实现,无法获取System.out.println("BootStrapClassLoader " + demo.getParent().getParent());//String,Integer 等基础均由 BootStrapClassLoader 加载ClassLoader c1 = String.class.getClassLoader();System.out.println("c1 " + c1);ClassLoader c2 = Integer.class.getClassLoader();System.out.println("c2 " + c2);}
}
package com.jysemel.java.basic.claasloader;public class ClassLoaderDemo1 {public static void main(String[] args) {//BootStrapClassLoaderSystem.out.println("BootStrapClassLoader " + System.getProperty("sun.boot.class.path"));//ExtClassLoaderSystem.out.println("ExtClassLoader " + System.getProperty("java.ext.dirs"));//AppClassLoaderSystem.out.println("AppClassLoader " + System.getProperty("java.class.path"));}
}

Image text

向上委托查找、向下委托加载

保护底层类不会被应用程序覆盖

如何打破双亲委派

常见原因

容器部署多个应用可能依赖不同版本三方类库,保证每个应用类库独立和相互隔离 支持

打破方式

通过spi机制,使用ServiceLoader.load去加载

通过自定义类加载器,继承classloader,重写loadclass方法

demo

spi

Image text

package com.jysemel.java.basic.claasloader;import com.jysemel.java.basic.claasloader.spi.SpiService;import java.util.ServiceLoader;public class SpiDemo {public static void main(String[] args) {ServiceLoader<SpiService> serviceLoader = ServiceLoader.load(SpiService.class);System.out.println("加载到的 spiService 实现:");for (SpiService spiService : serviceLoader) {spiService.execute();}}
}package com.jysemel.java.basic.claasloader.spi;public interface SpiService {void execute();}package com.jysemel.java.basic.claasloader.spi;public class SpiServiceImpl1 implements SpiService {@Overridepublic void execute() {System.out.println("SpiServiceImpl1 执行,当前线程: " + Thread.currentThread().getName());}
}package com.jysemel.java.basic.claasloader.spi;public class SpiServiceImpl2 implements SpiService {@Overridepublic void execute() {System.out.println("SpiServiceImpl2 执行,当前线程: " + Thread.currentThread().getName());}
}
重写loadClass()
package com.jysemel.java.basic.claasloader.loadclass;import java.io.*;public class MyClassLoader extends ClassLoader {@Overridepublic Class<?> loadClass(String name) throws ClassNotFoundException {System.out.println("MyClassLoader 尝试加载类: " + name);// 1. 检查类是否已被加载Class<?> loadedClass = findLoadedClass(name);if (loadedClass != null) {System.out.println("类已加载,直接返回: " + name);return loadedClass;}// 2. 尝试使用父加载器加载(双亲委派)try {Class<?> parentLoaded = super.loadClass(name);System.out.println("父加载器成功加载: " + name);return parentLoaded;} catch (ClassNotFoundException e) {System.out.println("父加载器无法加载: " + name);}// 3. 如果父加载器失败,自己尝试加载(本例未实现,直接抛出异常)// 实际中可以在这里添加 findClass 逻辑throw new ClassNotFoundException("类 " + name + " 找不到");}
}package com.jysemel.java.basic.claasloader.loadclass;public class Test {public static void main(String[] args) throws Exception {// 创建自定义类加载器实例MyClassLoader loader = new MyClassLoader();// 使用自定义加载器加载一个存在的类(如 java.lang.String)Class<?> stringClass = loader.loadClass("java.lang.String");System.out.println("加载 String 的类加载器: " + stringClass.getClassLoader());System.out.println("----------------------------");// 加载一个不存在的类(触发异常)try {Class<?> unknownClass = loader.loadClass("com.example.Unknown");} catch (ClassNotFoundException e) {System.out.println("捕获异常: " + e.getMessage());}}
}

jdk9之后变化

ExtClassLoader 被PlatformClassLoader取代
http://www.jsqmd.com/news/382395/

相关文章:

  • 研发数字化升级抓手:AI编程助手的实践路径与架构优势
  • Qt QPushButton 图标与文字组合显示
  • 【毕业设计】SpringBoot+Vue+MySQL +游戏交易系统平台源码+数据库+论文+部署文档
  • 白牦牛品牌2026排行速览:哪些品牌值得关注,白牦牛/鲜牛肉/牛肉/新鲜牛肉/天祝白牦牛肉/白牦牛肉,白牦牛供应厂家推荐 - 品牌推荐师
  • [深度学习网络从入门到入土] 使用块的网络VGG
  • 企业级+游戏交易系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • 待宰大鹅流泪引网友喊话“求放过”,专家:鹅的泪腺较发达,可能被异物碰到导致流泪——动物还是有灵性,尽量少吃肉,或者不吃
  • Java Web 中山社区医疗综合服务平台系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】
  • PC-windows电脑无法打开小米路由器2的共享文件服务
  • 【读论文】Agent复杂任务大开销的解法:Unsupervised Hierarchical Skill Discovery
  • SpringBoot+Vue Web农产品直卖平台管理平台源码【适合毕设/课设/学习】Java+MySQL
  • 前后端分离Spring Boot库存管理系统系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程
  • 详细介绍:基于SpringBoot的留言板
  • 详细介绍:Tomcat源码分析三(Tomcat请求源码分析)
  • 2026碳酸镁市场热门之选:这些厂家不容错过,优质的碳酸镁源头厂家10年质保有保障 - 品牌推荐师
  • 2026年2月14日
  • 龙魂家底评估报表(截至2026年2月)
  • 六、Claude Opus 4.6 对自己的评价
  • F1. Again Trees... (Easy Version)
  • 30-植物单细胞RNA-seq分析教程4-2025年版
  • 2026年2月数据恢复在路上:靠谱光盘抛光修复工具厂家推荐,NAS数据恢复软件/视频恢复取证软件,数据恢复直销厂家推荐 - 品牌推荐师
  • Analyzing Spring IOC Source Code
  • 无人机精准授粉,输入,花朵分布图,处理,规划授粉航线,输出,飞行路线。
  • 2026年2月北京丰台区老年社区推荐,高口碑养老机构精选 - 品牌鉴赏师
  • 【Azure App Service】为什么启用 Health Check 后应用服务实例持续显示 Unhealthy?
  • 专业之选:方盾半面罩在工业防护中的关键作用
  • 位运算与进制转化
  • 【Azure App Service】为何应用服务的Health Check功能返回403导致实例状态Unhealthy?
  • 实用指南:HarmonyOS智慧农业管理应用开发教程--高高种地---第1篇:项目初始化与环境搭建
  • 2026年质量好的碳纤维管抛光设备/碳纤维管烘干设备厂家信誉综合参考 - 行业平台推荐