什么是双亲委派机制?
双亲委派机制(Parent Delegation Mechanism)是Java中的一种类加载机制。在Java中,类加载器负责加载类的字节码并创建对应的Class对象。双亲委派机制是指当一个类加载器收到类加载请求时,它会先将该请求委派给它的父类加载器去尝试加载。只有当父类加载器无法加载该类时,子类加载器才会尝试加载。
双亲委派机制加载类流程
1、当加载一个类时,先判断此类是否已经被加载,如果类已经被加载则返回;
2、如果类没有被加载,则先委托父类加载(父类加载时会判断该类有没有被自己加载过),如果父类加载过则返回;如果没被加载过则继续向上委托;
自定义类加载器(自己指定目录中的class) —委托—>
应用程序类加载器(CLASS_PATH指定目录的所有jar) —委托—>
扩展类加载器(JRE/lib/ext/*.jar) —委托—>
启动类加载器(JRE/lib/rt.jar)
3、如果一直委托都无法加载,子类加载器才会尝试自己加载。
4、如果自身的加载机制仍然无法加载该类,则会抛出ClassNotFoundException异常。
双亲委派机制作用
避免类的重复加载,提高了类加载的效率和安全性。通过这种双亲委派的机制,Java实现了类加载的层次结构。它可以确保类的加载是有序的,避免了重复加载和类的冲突。同时,它也提供了一种安全机制,防止恶意代码的加载和执行。
如何打破双亲委派机制?
1、为什么要打破双亲委派机制?
有时我们需要多次加载同名目录下的类,比如:当我们部署多个服务时,不同服务上可能依赖了不同版本的第三方jar,如果此时使用双亲委派机制加载类,会导致多个服务中第三方jar只加载一次,其他服务中的其他版本jar将不会生效,导致请求结果异常。为了避免这种情况,我们需要打破双亲委派机制,不再让父类[应用类加载器]加载,而是为每个服务创建自己的子类加载器。
2、如何打破双亲委派机制?
就是不委托父加载,直接自己加载类。双亲委派的逻辑代码实现在loadClass方法中。需要继承ClassLoader重写loadClass方法即可,在调用的findClass里面加上类加载逻辑。
// 不是自己定义的类依旧按照原来的逻辑走【双亲委派类加载机制】
if (!name.endsWith(“test”)) {
return parent.loadClass(name);
}
// 获取类定义的加载路径,读取编译后的文件
return defineClass(null, bytes, 0, bytes.length)