双亲委派机制是Java类加载器的一种基础架构,它的作用是保证Java中类的安全性和稳定性。在Java中,类加载器主要分为三种:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。其中,Bootstrap ClassLoader是最顶层的类加载器,Extension ClassLoader和Application ClassLoader都是由它衍生而来。在双亲委派机制下,当一个类需要被加载时,会先被Application ClassLoader加载,如果Application ClassLoader发现该类还没有被加载,则会将加载请求委派给Extension ClassLoader;Extension ClassLoader如果也没有加载过该类,再将委派请求传递给Bootstrap ClassLoader进行加载。如果Bootstrap ClassLoader成功加载了该类,就会沿着委托链返回,让Extension ClassLoader和Application ClassLoader逐一进行加载。双亲委派机制的优点是保证了类的唯一性,避免了重复加载。
下面是一个简单的示例代码,演示了双亲委派机制的具体实现过程:public class ClassLoaderDemo {
public static void main(String[] args) {
ClassLoader loader = ClassLoaderDemo.class.getClassLoader();
System.out.println("当前类的加载器为:" + loader);
System.out.println("当前类的父加载器为:" + loader.getParent());
System.out.println("当前类的爷加载器为:" + loader.getParent().getParent());
}
}
当执行上面代码时,会输出如下信息:
当前类的加载器为:sun.misc.Launcher$AppClassLoader@18b4aac2
当前类的父加载器为:sun.misc.Launcher$ExtClassLoader@6f94fa3e
当前类的爷加载器为:null
其中,sun.misc.Launcher$AppClassLoader表示当前类的加载器为Application ClassLoader,它的父加载器是Extension ClassLoader,Extension ClassLoader的父加载器为Bootstrap ClassLoader。
接下来我们将介绍如何破坏双亲委派机制。在默认情况下,系统自动采用双亲委派机制,如果我们想打破这个机制,只需要自己定义一个类加载器,并且在该类加载器中覆盖loadClass()方法即可。示例代码如下:
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// 自定义类加载器的具体实现
return super.loadClass(name, resolve);
}
}
在自定义类加载器的loadClass()方法中,我们可以自己定义加载规则,从而打破双亲委派机制。
那么为什么要破坏双亲委派机制呢?主要因为在某些场景下,我们需要使用不同的类加载器来加载同一份字节码文件,例如在Java Web应用程序中,容器会使用不同的类加载器来分别加载应用程序中的类和Java类库中的类,从而避免类的冲突。此时,我们就需要破坏双亲委派机制,自定义类加载器来实现这个功能