?那意味着我们需要去打破双亲委派机制 。看AppClassLoader的类加载逻辑,主要逻辑在父类ClassLoader.loadClass()方法中 , 我们只需要在自定义的类加载器中重写该方法即可 。主要修改逻辑:如果类型是com.hyz.jvm开头的类,则从自定义类加载器中去读?。?否则委托给上层类加载器加载 。
/** * 32 * 重写类加载方法,实现自己的加载逻辑 , 不委派给双亲加载 * 33 * @param name * 34 * @param resolve * 35 * @return * 36 * @throws ClassNotFoundException * 37 */protected 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.hyz.jvm")) {c = this.getParent().loadClass(name);} else {c = findClass(name);}// this is the defining class loader; record the statssun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}if (resolve) {resolveClass(c);}return c;}}
?应用到打破双亲委派机制的实际应用场景是在Tomcat加载war包 。比如war1用的是spring4版本,war2用的是spring5版本,那就意味着加载着2个war包不能用同一个类加载器实例,需要各自指定一个自定义的类加载器实例,各自去加载所需的spring版本库文件 。
总结:双亲委派机制保证了核心类的安全,确保不会被修改,也保证了不会加载到重复的字节码文件 。
推荐阅读
- 万字详解JVM,让你一文吃透
- JVM学习笔记——类加载和字节码技术篇
- 详细了解JVM运行时内存
- 【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列
- JVM学习笔记——垃圾回收篇
- JVM学习笔记——内存结构篇
- JAVA系列之JVM内存调优
- JDK中自带的JVM分析工具
- 树的邻接矩阵、双亲孩子表示法…… C++ 不知树系列之初识树
- JVM、JDK、JRE你分的清吗