上文:jdk-Launcher源码学习


背景

上文说过,jdk是通过双亲委派机制实现类的加载,但是这个加载效率及场景存在弊端,所以本文借鉴tomcat的实现方式去打破双亲委派机制实现自定义类加载器来模似tomcat的类加载方式。

实现方式

实现思想:首先继承ClassLoader,然后通过classLoader进行重写findClass实现。

package com.classloader.simulate;import com.encryption.demo.EncryptionUtils;
import org.apache.commons.lang.StringUtils;import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** @author hong* @version 1.0* @description: 模似打破双亲委派机制* @date 2022/4/16 18:50*/
public class SimulateTomcatClassLoader  {static class MySelfClassLoader extends ClassLoader{/*** 类路劲**/private String classPath;public MySelfClassLoader(String classPath) {this.classPath = classPath;}private byte[] loadByClassName(String className) throws Exception {if (StringUtils.isEmpty(className)) {throw new Exception("类名不能为空!");}//替换路劲格式className = className.replaceAll("\\.", "/");//获取文件信息FileInputStream fis = new FileInputStream(classPath + "/" + className + ".class");//获取长度int len = fis.available();//文件信息byte[] data = new byte[len];//读写文件信息fis.read(data);fis.close();return data;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {byte[] data = loadByClassName(name);return defineClass(name, data, 0, data.length);} catch (Exception e) {e.printStackTrace();throw new ClassNotFoundException();}}/*** 重写类加载方法,在这里打破双亲委派* @param name* @param resolve* @return* @throws ClassNotFoundException*/@Overrideprotected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();//这里重写逻辑 如果不是自定义类开头就用默认类加载器,如果是就有自定义类加载器加载if(!name.startsWith("com.classloader")){c = this.getParent().loadClass(name);}else{c = findClass(name);}// this is the defining class loader; record the stats
// sun.misc.PerfCounter.getParentDelegationTime().addTime(t1);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}
// }if (resolve) {resolveClass(c);}return c;}}}public void test(){System.out.println("测试类!");}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//获取项目路劲File file = new File(EncryptionUtils.class.getResource("/").getPath());MySelfClassLoader mySelfClaasLoader = new MySelfClassLoader(file.getPath());Class<?> loadClass = mySelfClaasLoader.loadClass("com.classloader.simulate.SimulateTomcatClassLoader");//获取实例对象Object obj = loadClass.newInstance();//获取方法列表Method[] declaredMethods = loadClass.getDeclaredMethods();System.out.println(declaredMethods);//获取方法Method method = loadClass.getMethod("test", null);method.invoke(obj,null);System.out.println(loadClass.getClassLoader().getClass().getName());;}
}

结果

测试类!
com.classloader.simulate.SimulateTomcatClassLoader$MySelfClassLoader

最后

很多容器都是打破Jvm的双亲委派机制来实现的,比如tomcat,如果不打破的话根据无法部署多个项目,所以打破双亲委派机制也是一种业务场景的需要。而通过了解和实现打破双亲委派机制来学习tomcat的实现,有效提升对jvm底层的实现了解。

参考文章:

https://www.jianshu.com/p/7706a42ba200

https://cwiki.apache.org/confluence/display/tomcat/FAQ

https://blog.csdn.net/lisheng5218/article/details/111475536

如何打破双亲委派机制?相关推荐

  1. 如何打破双亲委派机制

    双亲委派机制 第一次知道何为打破双亲委派机制是通过阅读周志明的<深入理解Java虚拟机>,我们知道双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器 ...

  2. 【有料】面试必备:什么时候要打破双亲委派机制?什么是双亲委派? (图解+秒懂+史上最全)

    面试题:什么时候要打破双亲委派机制 来自社群的两个面试题,其实也是两个基础的 面试题,大家一定要掌握 社群问题: 先说下第一题的结论 场景1: 如果委托类没有实现接口的话,就不能使用newProxyI ...

  3. 双亲委派机制以及打破双亲委派机制

    双亲委派机制以及打破双亲委派机制 双亲委派机制 Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存中生成class对象,而且加载某个类的c ...

  4. Java打破双亲委派机制

    1.自定义加载器 沿用双亲委派机制自定义类加载器很简单,只需继承ClassLoader类并重写findClass方法即可. ①先定义一个待加载的类Test,它很简单,只是在构建函数中输出由哪个类加载器 ...

  5. 【JVM】Java类的加载流程以及双亲委派,全盘托管,以及如何打破双亲委派机制

    JVM基础生命周期流程图 只有main()方法的java程序执行流程 classLoader.loadClass()的类加载流程(除引导类,所有类都一样) 加载:通过IO查找读取磁盘上的字节码文件,在 ...

  6. 打破双亲委派机制有什么用_1.4 打破双亲委派机制

    什么是打破双亲委派机制呢? 那么这里第一步, 我们需要知道什么是双亲委派机制? 前面已经说了什么是双亲委派机制了, 那打破是怎么回事呢? 比如, 我现在有一个自定义类加载器, 加载的是~/com/lx ...

  7. 面试必备:什么时候要打破双亲委派机制?什么是双亲委派? (图解+秒懂+史上最全)

    文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 经典图书:<Java高并发核心编程(卷1)> 面试必备 ...

  8. JVM类加载机制、双亲委派机制、自定义类加载器、打破双亲委派机制

    1.类加载器 站在Java虚拟机的角度看,只有两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现(HotSpot虚拟机.JDK8中), ...

  9. Tomcat打破双亲委派机制

    打破双亲委派 沙箱安全机制示例,尝试打破双亲委派机制,用自定义类加载器加载自己实现的 java.lang.String.class public class MyClassLoaderTest {st ...

最新文章

  1. html怎么调整成苹方,html苹方字体
  2. 当 .NET 5 遇上OpenTelemetry,会碰撞出怎样的火花?
  3. 不用“背”单词,1个方法牢记7000单词:我是如何做到的?
  4. mysql batis传多个参数_Mybatis传多个参数(三种解决方案)
  5. 代码整洁之道(一)最佳实践小结 1
  6. 九章算法 | Facebook 面试题 : Backpack VI 背包算法
  7. Java项目课程02:系统概述
  8. VoIP之语音编码器
  9. Linux必会原理之软连接文件和硬链接文件的区别
  10. defaultView与currentStyle的区别_获取CSS样式值
  11. adb uninstall
  12. 完全卸载NI系列软件的方法
  13. 读取UYVY格式的YUV图片,并转为RGB格式
  14. Redis雪崩效应的解决方案(转)
  15. 句法结构分析:基于PCFG的基本分析方法
  16. Python实现飞翔的小鸟
  17. gitbook:gitbook-cli\node_modules\npm\node_modules\graceful-fs\polyfills.js
  18. latch 深入理解(转载)
  19. Linux内核模块管理
  20. Python中ASCII转十六进制、C中BCD转十进制、十六进制学习记录

热门文章

  1. 我脑中飘来飘去的 CSS 魔幻属性
  2. CCNP基础知识-路由(二)
  3. Syzmlw让子弹飞下载地址
  4. 小米电视的网页和珠宝的网页
  5. 石器时代单机版 – 80后的初恋网游
  6. 18 哈希算法的应用和一致性哈希
  7. 使用antd表格固定列后行与行之间对不齐
  8. ThreadPoolExecutor源码浅析
  9. Managing Non-Volatile Memory in Database Systems
  10. 程序员需要善于在工作中总结