java classLoader双亲委派源码分析

2022-04-19  本文已影响0人  zivxia

一个java程序被执行,编译器先将.java文件编译成class文件,然后classloader将class文件加载到jvm内存中来执行应用程序。classloader起到了至关重要的作用,下面我们来看下classloader的分类:

系统类加载器

自定义类加载器

就是我们自己写一个类继承ClassLoader,然后重写findClass方法加载指定目录下的class文件

classLoader继承关系

我们知道系统所提供的类加载器有3种类型,但是系统提供的ClassLoader相关类却不只3个。另外,AppClassLoader的父类加载器为ExtClassLoader,并不代表AppClassLoader继承自ExtClassLoader,ClassLoader的继承关系如下所示。


image.png

可以看到上图中共有5个ClassLoader相关类,下面简单对它们进行介绍:

双亲委派机制

类加载器查找Class所采用的是双亲委托模式,所谓双亲委托模式就是首先判断该Class是否已经加载,如果没有则不是自身去查找而是委托给父加载器进行查找,这样依次的进行递归,直到委托到最顶层的Bootstrap ClassLoader,如果Bootstrap ClassLoader找到了该Class,就会直接返回,如果没找到,则继续依次向下查找,如果还没找到则最后会交由自身去查找。

image.png

这样讲可能会有些抽象,来直接看源码:

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);//第一步
            if (c == null) {
                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.
                    c = findClass(name);
                }
            }
            return c;
    }

    protected final Class<?> findLoadedClass(String name) {
        ClassLoader loader;
        if (this == BootClassLoader.getInstance())
            loader = null;
        else
            loader = this;
        return VMClassLoader.findLoadedClass(loader, name);
    }

两个过程,先从下到上查询是否有类加载器加载过该class,然后从上到下询问类加载器是否可以加载该class

双亲委托模式的好处

采取双亲委托模式主要有两点好处:

上一篇 下一篇

猜你喜欢

热点阅读