浅谈一下Java的双亲委派模式

 更新时间:2023年04月27日 08:53:39   作者:索码理  
这篇文章主要介绍了一下Java的双亲委派模式,双亲委派指得是,JVM在加载类时,会委派给ExtClassLoader和BootstrapClassLoader进⾏加载,如果没加载到才由⾃⼰进⾏加载,需要的朋友可以参考下

说起双亲委派模型,不得不说一下类加载器。

类加载器是什么?

当我们编译Java类时,JVM会创建与平台和机器无关的字节码。字节码存储在.class文件中。当我们尝试使用一个类时,类加载器就会把它加载到内存中,然后把字节码文件转成Class对象。通俗的说类加载器就是将.class文件转成Class对象的。

类加载器分类

启动类加载器(Bootstrap Class Loader):负责加载存放在 <JAVA_HOME>\lib目录下的类,或者被-Xbootclasspath参数所指定的路径中存放的类。比如:rt.jarjava.lang.*包下的类。

扩展类加载器(Extension Class Loader):负责加载<JAVA_HOME>\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有的类库。

应用程序类加载器(Application Class Loader):负责加载用户类路径上所有的类库。

双亲委派模型工作流程

当类加载器收到加载类的请求时,它首先会把请求委派给父加载器去完成,每一层都如此,直到把请求委派给最顶层的启动类加载器,只有当父加载器无法加载委派过来的类时,子加载器才会加载。

JVM在加载⼀个类时,会调⽤AppClassLoader的loadClass⽅法来加载这个类,不过在这个⽅法中,会先使⽤ExtClassLoader的loadClass⽅法来加载类,同样ExtClassLoader的loadClass⽅法中会先使⽤BootstrapClassLoader来加载类,如果BootstrapClassLoader加载到了就直接成功,如果 BootstrapClassLoader没有加载到,那么ExtClassLoader就会⾃⼰尝试加载该类,如果没有加载到,那么则会由AppClassLoader来加载这个类。

双亲委派模型

所以,双亲委派指得是,JVM在加载类时,会委派给ExtClassLoader和BootstrapClassLoader进⾏加载,如果没加载到才由⾃⼰进⾏加载。

这里说的双亲并不是说类加载器之间是以继承方式实现的,而是以组合的方式实现的,通过源码可以证实这点:

java.lang.ClassLoader#loadClass

private final ClassLoader parent;

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

同时,通过源码我们也可以看到类加载器的加载流程是跟我们描述的一样的:先检查请求加载的类型是否已经被加载过,若没有则调用父加载器的loadClass()方法,若父加载器为空则默认使用启动类加载器作为父加载器。假如父类加载器加载失败,抛出ClassNotFoundException异常的话,才调用自己的findClass()方法尝试进行加载。

双亲委派模型好处

保证唯一性,避免重复加载:类的加载随着它的类加载器一起具备了层级关系,通过这种层级关系避免了重复加载,父类加载器加载了该类,子加载器就无需加载了。

避免核心类被篡改:核心类由启动类加载器加载,即使用户自定义同名核心类也不会被加载。

到此这篇关于浅谈一下Java的双亲委派模式的文章就介绍到这了,更多相关java双亲委派模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Java动态代理的实现

    浅谈Java动态代理的实现

    最近,小组同事做代码改造时,使用到了动态代理,自己阅读时,发现对代理这种设计模式都不怎么清楚,导致理解代码也很困难 自己唯一能看懂的,大概就是handler中的invoke方法 ,文中作出了非常详细的介绍,需要的朋友可以参考下
    2021-05-05
  • Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决

    Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决

    这篇文章主要介绍了Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决,文章围绕主题展开详细的内容介绍,具有一定的参考一下
    2022-08-08
  • Java后端登录实现返回token

    Java后端登录实现返回token

    本文主要介绍了Java后端登录实现返回token,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • RocketMQ中消费者概念和消费流程详解

    RocketMQ中消费者概念和消费流程详解

    这篇文章主要介绍了RocketMQ中消费者概念和消费流程详解,RocketMQ是一款高性能、高可靠性的分布式消息中间件,消费者是RocketMQ中的重要组成部分,消费者负责从消息队列中获取消息并进行处理,需要的朋友可以参考下
    2023-10-10
  • 浅谈使用Maven插件构建Docker镜像的方法

    浅谈使用Maven插件构建Docker镜像的方法

    本篇文章主要介绍了浅谈使用Maven插件构建Docker镜像的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • JDK8时间相关类超详细总结(含多个实例)

    JDK8时间相关类超详细总结(含多个实例)

    jdk1.8的一些新特性简化了代码的写法,减少了部分开发量,下面这篇文章主要给大家介绍了关于JDK8时间相关类超详细总结,文中包含了多个实例代码,需要的朋友可以参考下
    2023-01-01
  • Java设计模式之责任链模式的示例详解

    Java设计模式之责任链模式的示例详解

    责任链模式是将链中的每一个节点看做是一个对象,每个节点处理的请求均不相同,且内部自动维护下一个节点对象,当一个请求从链式的首段发出时,会沿着链的路径依次传递给每一个节点对象。本文将通过示例和大家详细聊聊责任链模式,需要的可以参考一下
    2022-11-11
  • Java设计模式之策略模式示例详解

    Java设计模式之策略模式示例详解

    策略模式属于Java 23种设计模式中行为模式之一,该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。本文将通过示例详细讲解这一模式,需要的可以参考一下
    2022-03-03
  • java 读取excel内容具体代码

    java 读取excel内容具体代码

    这篇文章介绍了java 读取excel内容具体代码,有需要的朋友可以参考一下
    2013-10-10
  • idea2022创建javaweb项目步骤(超详细)

    idea2022创建javaweb项目步骤(超详细)

    本文主要介绍了idea2022创建javaweb项目步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07

最新评论