• 双亲委派机制


    前言

    我们在IDE中编写的Java源代码被编译器编译成.class的字节码文件。然后由ClassLoader(类加载器)负责将这些.class文件加载到JVM中去执行。

    ClassLoader

    Bootstrap ClassLoader(启动类加载器)
      C++实现 在java里无法获取 负责加载<JAVA_HOME>/lib下的类
    Extension ClassLoader (标准扩展类加载器)
      Java实现 可以在java里获取 负责加载<JAVA_HOME>/lib/ext下的类
    Application ClassLoader(系统类加载器)
      代码默认就是由它来加载, ClassLoader.getSystemClassLoader返回的就是它

    双亲委派机制

    当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。如下图:

    1,Application ClassLoader 在自己的加载范围中查看是否加载过?  
        是->已经加载过则不再次加载 
        否->未加载过则交给父加载器 Extension ClassLoader
    2,Extension ClassLoader 在自己的加载范围中查看是否加载过?  
        是->已经加载过则不再次加载  
        否->未加载过则交给父加载器 Bootstrap ClassLoader
    3,Bootstrap ClassLoader 在自己的加载范围中查看是否加载过?  
        是->已经加载过则不再次加载  
        否->未加载过则判断自己是否可以加载此类
            是->可以加载此类则自己加载此类 
            否->不能加载则交给子加载器 Extension ClassLoader
    4,Extension ClassLoader 判断是否可以加载此类 
        是->可以加载此类则自己加载此类 
        否->不能加载则交给子加载器 Application ClassLoader
    5,Application ClassLoader 判断是否可以加载此类 
        是->可以加载此类则自己加载此类
        否->ClassNotFoundException
    上图中的CustomClassLoader是自定义类加载器, 可以作为打破双亲委派机制的的一种方式, 原理就是我们自己编写自定义类加载器, 在该类加载器中加载特定的.class文件, 那么就不会再继续委托给上级类加载器了

    双亲委派机制的作用

    1、防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
    2、保证核心.class不能被篡改。通过委托方式,不会去篡改核心.class,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

    打破双亲委派机制

    为什么要打破双亲委派

    双亲委托模型并不是一个强制性的约束模型,而是java设计者推荐给开发者的泪加载器实现方式。但是双亲委托模型存在着缺陷,它虽然解决了各个类加载器的基础类的统一问题,基础被称为基础,就是因为他们总是被用户代码调用,但是如果基础类又要调用回用户代码呢?那么在就会使用基础类的类加载器(启动类加载器)去加载用户的代码,而启动类加载器是加载java_homelib目录下的。而用户代码都是保存在classpath下,根本就不可能加载到。

    如何打破双亲委派

    1,自定义加载器

    2,通过线程上下文类加载器:类加载器入口 sun.misc.Launcher 将 Application ClassLoader 设置成线程上下文类加载器: Thread.currentThread().setContextClassLoader(xxxx) ,,也可以通过这个方法将其他的类加载器设置成现成上下文类加载器;然后底层类加载器可以通过Thread.currentThread().getContextClassLoader() 获取之前指定的类加载器,进而加载需要加载的.class文件。

  • 相关阅读:
    testNG参数传递方式
    TestNG超详细教程
    testNG中@Factory详解
    【转】HashMap的工作原理
    shell脚本学习笔记
    awk文本处理知识汇总
    sed文本处理知识点整理
    oracle数据库sql的基本使用
    【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例
    HTML5 indexedDB数据库的入门学习(二)
  • 原文地址:https://www.cnblogs.com/blazeZzz/p/13029865.html
Copyright © 2020-2023  润新知