浅谈一下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双亲委派模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring boot项目自定义参数校验规则示例详解

    spring boot项目自定义参数校验规则示例详解

    这篇文章主要介绍了spring boot项目如何自定义参数校验规则,自定义校验规则和自带的规则实现方式一样,先自定义一个注解,然后指定校验类,在校验类里实现具体的校验规则,本文结合示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • HttpServletRequest对象方法的用法小结

    HttpServletRequest对象方法的用法小结

    HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的相关方法,即可以获得客户的这些信息
    2017-03-03
  • java之使用stream对日期排序方式

    java之使用stream对日期排序方式

    这篇文章主要介绍了java之使用stream对日期排序方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • springMVC获取请求参数的几种方式汇总

    springMVC获取请求参数的几种方式汇总

    在日常使用SpringMVC进行开发的时候,有可能遇到前端各种类型的请求参数,这里做一次相对全面的总结,下面这篇文章主要给大家介绍了关于springMVC获取请求参数的几种方式,需要的朋友可以参考下
    2022-04-04
  • Java Excel文件加密保护数据安全

    Java Excel文件加密保护数据安全

    这篇文章主要为大家介绍了Java Excel文件加密保护数据安全的方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • 详解JAVA 时间处理相关类

    详解JAVA 时间处理相关类

    这篇文章主要介绍了JAVA 时间处理相关类的知识,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • Java读取Excel文件内容的简单实例

    Java读取Excel文件内容的简单实例

    这篇文章主要介绍了Java读取Excel文件内容的简单实例,有需要的朋友可以参考一下
    2013-11-11
  • 全网最精细详解二叉树,2万字带你进入算法领域

    全网最精细详解二叉树,2万字带你进入算法领域

    大家好,我是哪吒,一个热爱编码的Java工程师,本着"欲速则不达,欲达则欲速"的学习态度,在程序猿这条不归路上不断成长,所谓成长,不过是用时间慢慢擦亮你的眼睛,少时看重的,年长后却视若鸿毛,少时看轻的,年长后却视若泰山,成长之路,亦是渐渐放下执念,内心归于平静的旅程
    2021-08-08
  • mybatis 为什么千万不要使用 where 1=1

    mybatis 为什么千万不要使用 where 1=1

    这篇文章主要介绍了mybatis 为什么千万不要使用 where 1=1,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • spring是如何实现声明式事务的

    spring是如何实现声明式事务的

    这篇文章主要介绍了spring是如何实现声明式事务的,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04

最新评论