如何打破双亲委派机制?
上文: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
如何打破双亲委派机制?相关推荐
- 如何打破双亲委派机制
双亲委派机制 第一次知道何为打破双亲委派机制是通过阅读周志明的<深入理解Java虚拟机>,我们知道双亲委派机制是指当一个类加载器收到一个类加载请求时,该类加载器首先会把请求委派给父类加载器 ...
- 【有料】面试必备:什么时候要打破双亲委派机制?什么是双亲委派? (图解+秒懂+史上最全)
面试题:什么时候要打破双亲委派机制 来自社群的两个面试题,其实也是两个基础的 面试题,大家一定要掌握 社群问题: 先说下第一题的结论 场景1: 如果委托类没有实现接口的话,就不能使用newProxyI ...
- 双亲委派机制以及打破双亲委派机制
双亲委派机制以及打破双亲委派机制 双亲委派机制 Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存中生成class对象,而且加载某个类的c ...
- Java打破双亲委派机制
1.自定义加载器 沿用双亲委派机制自定义类加载器很简单,只需继承ClassLoader类并重写findClass方法即可. ①先定义一个待加载的类Test,它很简单,只是在构建函数中输出由哪个类加载器 ...
- 【JVM】Java类的加载流程以及双亲委派,全盘托管,以及如何打破双亲委派机制
JVM基础生命周期流程图 只有main()方法的java程序执行流程 classLoader.loadClass()的类加载流程(除引导类,所有类都一样) 加载:通过IO查找读取磁盘上的字节码文件,在 ...
- 打破双亲委派机制有什么用_1.4 打破双亲委派机制
什么是打破双亲委派机制呢? 那么这里第一步, 我们需要知道什么是双亲委派机制? 前面已经说了什么是双亲委派机制了, 那打破是怎么回事呢? 比如, 我现在有一个自定义类加载器, 加载的是~/com/lx ...
- 面试必备:什么时候要打破双亲委派机制?什么是双亲委派? (图解+秒懂+史上最全)
文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 经典图书:<Java高并发核心编程(卷1)> 面试必备 ...
- JVM类加载机制、双亲委派机制、自定义类加载器、打破双亲委派机制
1.类加载器 站在Java虚拟机的角度看,只有两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现(HotSpot虚拟机.JDK8中), ...
- Tomcat打破双亲委派机制
打破双亲委派 沙箱安全机制示例,尝试打破双亲委派机制,用自定义类加载器加载自己实现的 java.lang.String.class public class MyClassLoaderTest {st ...
最新文章
- html怎么调整成苹方,html苹方字体
- 当 .NET 5 遇上OpenTelemetry,会碰撞出怎样的火花?
- 不用“背”单词,1个方法牢记7000单词:我是如何做到的?
- mysql batis传多个参数_Mybatis传多个参数(三种解决方案)
- 代码整洁之道(一)最佳实践小结 1
- 九章算法 | Facebook 面试题 : Backpack VI 背包算法
- Java项目课程02:系统概述
- VoIP之语音编码器
- Linux必会原理之软连接文件和硬链接文件的区别
- defaultView与currentStyle的区别_获取CSS样式值
- adb uninstall
- 完全卸载NI系列软件的方法
- 读取UYVY格式的YUV图片,并转为RGB格式
- Redis雪崩效应的解决方案(转)
- 句法结构分析:基于PCFG的基本分析方法
- Python实现飞翔的小鸟
- gitbook:gitbook-cli\node_modules\npm\node_modules\graceful-fs\polyfills.js
- latch 深入理解(转载)
- Linux内核模块管理
- Python中ASCII转十六进制、C中BCD转十进制、十六进制学习记录