最近在做一些项目,需要破坏Java的双亲委派,查了一些资料,记录了一下双亲委派的一些机制,以及破坏后我们可以实现拿些功能,其实之前大学学过一段时间,但是忘得差不多了
一、双亲委派机制简介
双亲委派机制的核心思想是:类加载时,首先委派给父类加载器加载,如果父类加载器无法加载,再由子类加载器尝试加载。具体步骤如下:
- 检查当前加载请求是否由Bootstrap ClassLoader加载:如果是,则直接加载,否则继续委派。
- 检查当前加载请求是否由Extension ClassLoader加载:如果是,则直接加载,否则继续委派。
- 检查当前加载请求是否由Application ClassLoader加载:如果是,则直接加载,否则继续委派。
- 如果父加载器都无法加载,则由当前ClassLoader加载。
这种机制保证了Java核心库的优先加载,避免了自定义类覆盖核心类的问题。
二、为什么要破坏双亲委派机制
尽管双亲委派机制具有很高的安全性和稳定性,但在某些特殊场景下,我们需要打破这种机制:
- 动态加载不同版本的类:在热部署、模块化系统中,可能需要加载不同版本的类。
- 隔离不同模块的类:在某些大型系统中,需要隔离不同模块的类加载,以避免类冲突。
- 加载外部资源或插件:某些插件系统需要动态加载外部资源或插件,这些资源可能不在应用的类路径中。
三、自定义ClassLoader基础
在Java中,自定义ClassLoader只需继承java.lang.ClassLoader
类,并重写其findClass
方法。下面是一个简单的自定义ClassLoader示例:
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 获取类的字节码(通常从文件或网络加载)
byte[] classData = loadClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
}
// 将字节码转换为Class对象
return defineClass(name, classData, 0, classData.length);
}
private