双亲委派模型是Java类加载器的一种工作模式。通过这种工作方式,Java虚拟机将class文件加载到内存中,从而保证Java程序能够正常运行。那么双亲委派模式到底是什么?接下来我们一起来看看吧。1、类加载器双亲委托模型针对的是Java虚拟机中的三个类加载器。这三个类加载器分别是:BootstrapClassLoader、ExtensionClassLoader、应用类加载器(ApplicationClassLoader)如下图所示:这三个类加载器的作用如下。1.1BootstrapClassLoaderBootstrapClassLoader是C++实现的,用于加载\jre\lib\rt.jar和resources.jar等jar包,如下图所示:接下来我们写一段代码到测试rt类加载器的打印:publicclassClassLoaderExample{publicstaticvoidmain(String[]args){//rt类下的ClassLoaderprintsSystem.out.println("rtclassloader:"+String.class.getClassLoader());}}上面程序的执行结果如下图所示:问题来了,为什么打印的不是null,而是“BootstrapClassLoader”呢?这是因为引导类加载器(BootstrapClassLoader)是C++实现的,而C++实现的类加载器在Java中没有对应的类,所以得到的结果为null。1.2扩展类加载器扩展类加载器用于加载\jre\lib\ext目录下的jar包,如下图:下面我们用代码来演示ext类加载器。示例代码如下:publicclassClassLoaderExample{publicstaticvoidmain(String[]args){//打印ext下的classloaderclassSystem.out.println("extclassloader:"+sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());}}上述程序的执行结果如下图所示:1.3应用类加载器应用类加载器用于加载类路径,即用户的所有类。接下来,我们编写代码来测试应用类加载实现代码如下:());}}上面程序的执行结果如下图所示:2.双亲委派模型双亲委派模型的执行过程如下:1.加载一个类时,会先从类中查找对应的类应用类加载器的缓存,如果能找到则返回,如果找不到则执行下面的流程;2、在扩展加载器缓存中查找对应的类,如果能找到就返回对象,如果找不到则继续下面的流程;3、在启动类加载器中查询对应的类,如果找到该类,则返回该对象,如果没有找到,继续下面的流程;4.在扩展加载器中查找并加载类,如果找到则返回对象,将对象添加到缓存中,如果找不到则继续下面的过程;5.在应用程序类加载器中搜索并加载类,如果能找到则返回对象,并将该对象加入缓存,如果找不到则返回ClassNotFound异常。加载过程如下图所示:一般“父母”指的是“父亲”和“母亲”,但这里的“父母”指的是先向上查找再向下查找类加载类的过程,称为双亲委托模型。三、优缺点分析3.1优点双亲委派模式有两个优点:1、安全。2.避免重复加载。3.1.1安全性在安全性能方面,在使用双亲委派模型时,用户不能伪造一些不安全的系统类,比如jre中已经提供了String类,在启动类加载时加载,那么用户-defined自定义不安全String类时,不会按照双亲委托模型加载用户定义的不安全String类,从而避免不安全问题。3.1.2避免重复加载使用双亲委托模型也可以避免一个类被重复加载。当加载一个类时,由于使用了双亲委派模型,多个类加载器不会重复加载同一个类。情况已经过去了。3.2缺点双亲委托模型的典型问题是加载SPI实现类的场景,比如JNDI(JavaNamingandDirectoryInterface,Java命名和目录接口)服务,其代码由启动类加载器加载(放在JDK中1.3rt.jar),但JNDI的目的是集中管理和查找资源。它需要在应用程序的类路径下调用独立厂商实现部门部署的JNDI接口提供者(SPI,ServiceProviderInterface)的代码,但是启动类加载器不可能“知道”一些代码,这是双亲委派模型的问题,JDBC也是同样的问题。总结双亲委派模型是Java中多个类加载器(启动类加载器、扩展加载器、应用类加载器)的运行规则。通过这个(双亲委派模型)规则,可以避免类和类加载器的非安全问题。反复加载的问题,但是也遇到了一些问题,比如JNDI和JDBC不能按这个规则加载,需要打破双亲委派的模型来加载。