美文网首页
Java双亲委派机制

Java双亲委派机制

作者: OhIAm | 来源:发表于2021-08-02 11:42 被阅读0次

一.Java有4种类加载器

  1. Bootstrap ClassLoader(启动类加载器):加载<JAVA_HOME>\lib路径下的类库,通常是rt.jar
  2. Extension ClassLoader (扩展类加载器) : 加载<JAVA_HOME>\lib\ext路径下的类库
  3. Application ClassLoader(应用程序类加载器):加载用户类路径(classpath)(没有指定的话通常指应用程序的当前目录)上的类库。
  4. User ClassLoader(用户自定义类加载器):继承ClassLoader,加载指定路径的class文件

二. 双亲委派模型的工作过程:

如果一个类加载器收到类加载的请求,它首先不会自己尝试去加载这个类,而是把这个请求委派给父加载器去完成。每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求,子加载器才会尝试自己去加载。

三.为什么要使用双亲委派模型:

  1. 为了保证Java程序的安全,如java.lang.Object是所有类的父类,如果用户自己编写了一个同样限定名的类,放在程序的classpath中,那系统中将会出现多个不同的Object类,Java类型体系中最基础的行为也就无法保证,应用程序也会变得一片换乱。
    所以是为了避免用户自己编写的类动态替换Java的一些核心类。如Object,String
  2. 避免类的重复加载,因为JVM中区分不同类,不仅仅是根据类名,相同的class文件被不同的ClassLoader加载就是不同的两个类。

四. 双亲委派模型的实现代码

java.lang.ClassLoader的loadClass()方法

protected synchronized Class<?> loadClass(String name, boolean resolve) 
throws ClassNotFoundException  {
        //首先检查请求的类是否已经被加载过了
        Class c = findLoadedClass(name);
        if(c == null) {
            try {
              //没有加载则调用父加载器的loadClass方法
                if(parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                //若父加载器为空则默认使用启动器类加载器作为父加载器。
                        c = findBootstrapClassOrNull(name);
                    }
              }
          catch(ClassNotFoundException e){
                //如果父类加载器加载失败,说明父类加载器无法完成加载请求
            }
          if(c == null) {
                  //在父类加载器无法加载的时候
                //再调用本身的findClass()方法来进行类加载
                c = findClass(name);
              }
        }
    if(resolve)  {
          resolveClass(c);
        }
return c;
  }

上面有3个方法需要注意:

  • loadClass: 主要进行类加载的方法,默认的双亲委派机制就实现在这个方法。
  • findClass:根据名字加载字节码
  • defineClass: 把字节码转化成Class类

五.破坏双亲委派模型

双亲委派过程都在loadClass方法内,想要破坏这种机制,重写其中的loadClass方法,使其不进行双亲委派即可。

  • 双亲委派被破坏的例子
  1. 双亲委派出现之前
    JDK1.2之后才引入双亲委派模型,在这之前用户自定义的类加载器肯定是没有遵循双亲委派原则。
  2. JNDI、JBDC等需要加载SPI接口实现类的情况
    JNDI、JDBC通过引入ThreadContextClassLoader(线程上下文加载器,默认就是应用程序类加载器)的方式破坏双亲委派原则。JNDI使用线程上下文加载器去加载所需要的SPI代码,就是父类加载器请求子类加载器去完成类加载的动作,而不是双亲委派模型中先委托父类加载,再由子类加载的原则。

相关文章

  • 从类加载开始的JVM学习

    目录 引言 java类加载流程 java类加载机制- 类加载原理- 双亲委派机制 Tomcat中双亲委派机制的应用...

  • Tomcat类载入器

    大家都知道,Java的类加载机制是双亲委派模型,那么什么是双亲委派模型呢?我们这里简要的说一下,双亲委派模型...

  • 简单了解什么是双亲委派机制?

    什么是双亲委派机制 了解双亲委派,需要先了解下JAVA的类加载器ClassLoader,java的类加载器主要有以...

  • 为什么使用双亲委派机制?

    为什么使用双亲委派机制? 专业名词 说双亲委派机制就不得不说类加载器。 引导类加载器:加载%JAVA_HOME%/...

  • JVM双亲委派机制

    什么是双亲委派机制? 要想搞明白什么是双亲委派机制就要先知道三个概念 1. 什么是类的加载? 将java代码通过类...

  • Java双亲委派机制

    什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个...

  • Java双亲委派机制

    一.Java有4种类加载器 Bootstrap ClassLoader(启动类加载器):加载...

  • Java双亲委派机制

    类加载器bootstrp c++ 编写,开发者无法直接获取到启动类加载器的引用ext 如classpath中...

  • JAVA 双亲委派机制

    java语言中支持4种类加载器: Bootstrap ClassLoader 启动类加载器 Extention C...

  • 为什么说SPI打破双亲委派机制

    简单介绍ClassLoader的双亲委派机制: java类通过Classloader加载,Classloader之...

网友评论

      本文标题:Java双亲委派机制

      本文链接:https://www.haomeiwen.com/subject/iqidvltx.html