美文网首页
常说的“双亲委派”中,双亲指的是什么?

常说的“双亲委派”中,双亲指的是什么?

作者: Depro | 来源:发表于2021-08-06 12:20 被阅读0次
  1. jvm有4咱classLoader,从低到高
  • BootstrapClassLoad,C++写的,java代码里没有
  • ExtClassLoader,java写的
  • AppClassLoader,java写的
  • 自定义ClassLoader,java写的
  1. 双亲应该是直译了parent,感觉说父类委托也行。其实是一个组合关系,如果当前ClassLoader有parent属性,就直接先parent来loadClass();这个parent有固定关系的:AppClassLoader的parent=ExtClassLoader, ExtClassLoader的parent=BootstrapClassLoader;所以一定会先由BootstrapClassLoader来加载类的;
    下面只摘取了部分关键代码
public abstract class ClassLoader {
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
           //这个是当前ClassLoader的缓存中取Class
            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
    }
            return c;
        }
    }
}
  1. AppClassLoader的parent=ExtClassLoader,
    这几个固定关系是怎么设置的?整个逻辑只列关键点
protected ClassLoader() {
        this(checkCreateClassLoader(), getSystemClassLoader());
    }

public static ClassLoader getSystemClassLoader() {
        initSystemClassLoader();
        if (scl == null) {
            return null;
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkClassLoaderPermission(scl, Reflection.getCallerClass());
        }
        return scl;
    }

private static synchronized void initSystemClassLoader() {
        if (!sclSet) {
            if (scl != null)
                throw new IllegalStateException("recursive invocation");

         sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
            if (l != null) {
                Throwable oops = null;
                scl = l.getClassLoader();
                try {
                    scl = AccessController.doPrivileged(
                        new SystemClassLoaderAction(scl));
                } catch (PrivilegedActionException pae) {
                    oops = pae.getCause();
                    if (oops instanceof InvocationTargetException) {
                        oops = oops.getCause();
                    }
                }
                if (oops != null) {
                    if (oops instanceof Error) {
                        throw (Error) oops;
                    } else {
                        // wrap the exception
                        throw new Error(oops);
                    }
                }
            }
            sclSet = true;
        }
    }

public static Launcher getLauncher() {
        return launcher;
    }

private static Launcher launcher = new Launcher();

public Launcher() {
        Launcher.ExtClassLoader var1;
        try {
            var1 = Launcher.ExtClassLoader.getExtClassLoader();
        } catch (IOException var10) {
            throw new InternalError("Could not create extension class loader", var10);
        }

        try {
//设置parent关键点,这里把ExtClassLoader传给了getAppClassLoader(var1)
            this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
        } catch (IOException var9) {
            throw new InternalError("Could not create application class loader", var9);
        }

        Thread.currentThread().setContextClassLoader(this.loader);
        String var2 = System.getProperty("java.security.manager");
        if (var2 != null) {
            SecurityManager var3 = null;
            if (!"".equals(var2) && !"default".equals(var2)) {
                try {
                    var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
                } catch (IllegalAccessException var5) {
                } catch (InstantiationException var6) {
                } catch (ClassNotFoundException var7) {
                } catch (ClassCastException var8) {
                }
            } else {
                var3 = new SecurityManager();
            }

            if (var3 == null) {
                throw new InternalError("Could not create SecurityManager: " + var2);
            }

            System.setSecurityManager(var3);
        }
    }

   static class AppClassLoader extends URLClassLoader {
        final URLClassPath ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this);

//这里的var0就是ExtClassLoader
        public static ClassLoader getAppClassLoader(final ClassLoader var0) throws IOException {
            final String var1 = System.getProperty("java.class.path");
            final File[] var2 = var1 == null ? new File[0] : Launcher.getClassPath(var1);
            return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction<Launcher.AppClassLoader>() {
                public Launcher.AppClassLoader run() {
                    URL[] var1x = var1 == null ? new URL[0] : Launcher.pathToURLs(var2);
                    return new Launcher.AppClassLoader(var1x, var0);
                }
            });
        }
}

//这里的var2就是ExtClassLoader
AppClassLoader(URL[] var1, ClassLoader var2) {
            super(var1, var2, Launcher.factory);
            this.ucp.initLookupCache(this);
        }

 public URLClassLoader(URL[] urls, ClassLoader parent,
                          URLStreamHandlerFactory factory) {
        super(parent);
        // this is to make the stack depth consistent with 1.1
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkCreateClassLoader();
        }
        acc = AccessController.getContext();
        ucp = new URLClassPath(urls, factory, acc);
    }

 protected SecureClassLoader(ClassLoader parent) {
        super(parent);
        // this is to make the stack depth consistent with 1.1
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkCreateClassLoader();
        }
        initialized = true;
    }

protected ClassLoader(ClassLoader parent) {
        this(checkCreateClassLoader(), parent);
    }

 private ClassLoader(Void unused, ClassLoader parent) {
//把ExtClassLoader一路传到这里
        this.parent = parent;
        if (ParallelLoaders.isRegistered(this.getClass())) {
            parallelLockMap = new ConcurrentHashMap<>();
            package2certs = new ConcurrentHashMap<>();
            domains =
                Collections.synchronizedSet(new HashSet<ProtectionDomain>());
            assertionLock = new Object();
        } else {
            // no finer-grained lock; lock on the classloader instance
            parallelLockMap = null;
            package2certs = new Hashtable<>();
            domains = new HashSet<>();
            assertionLock = this;
        }
    }
  1. ExtClassLoader的parent=BootstrapClassLoader
 protected ClassLoader() {
        this(checkCreateClassLoader(), getSystemClassLoader());
    }

 @CallerSensitive
    public static ClassLoader getSystemClassLoader() {
        initSystemClassLoader();
        if (scl == null) {
            return null;
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkClassLoaderPermission(scl, Reflection.getCallerClass());
        }
        return scl;
    }

private static synchronized void initSystemClassLoader() {
        if (!sclSet) {
            if (scl != null)
                throw new IllegalStateException("recursive invocation");
            sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
            if (l != null) {
                Throwable oops = null;
                scl = l.getClassLoader();
                try {
                    scl = AccessController.doPrivileged(
                        new SystemClassLoaderAction(scl));
                } catch (PrivilegedActionException pae) {
                    oops = pae.getCause();
                    if (oops instanceof InvocationTargetException) {
                        oops = oops.getCause();
                    }
                }
                if (oops != null) {
                    if (oops instanceof Error) {
                        throw (Error) oops;
                    } else {
                        // wrap the exception
                        throw new Error(oops);
                    }
                }
            }
            sclSet = true;
        }
    }

 public static Launcher getLauncher() {
        return launcher;
    }

public Launcher() {
        Launcher.ExtClassLoader var1;
        try {
          //这里没有传入参数,后面设置parent=null,在loadClass()方法时如果parent=null,就直接用BootstrapClassLoader加载了
            var1 = Launcher.ExtClassLoader.getExtClassLoader();
        } catch (IOException var10) {
            throw new InternalError("Could not create extension class loader", var10);
        }

        try {
            this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
        } catch (IOException var9) {
            throw new InternalError("Could not create application class loader", var9);
        }

        Thread.currentThread().setContextClassLoader(this.loader);
        String var2 = System.getProperty("java.security.manager");
        if (var2 != null) {
            SecurityManager var3 = null;
            if (!"".equals(var2) && !"default".equals(var2)) {
                try {
                    var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
                } catch (IllegalAccessException var5) {
                } catch (InstantiationException var6) {
                } catch (ClassNotFoundException var7) {
                } catch (ClassCastException var8) {
                }
            } else {
                var3 = new SecurityManager();
            }

            if (var3 == null) {
                throw new InternalError("Could not create SecurityManager: " + var2);
            }

            System.setSecurityManager(var3);
        }

    }




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 {
//因为ExtClassLoader就没有设置parent,所以会走这个方法
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }}}

相关文章

  • 常说的“双亲委派”中,双亲指的是什么?

    jvm有4咱classLoader,从低到高 BootstrapClassLoad,C++写的,java代码里没有...

  • Tomcat类载入器

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

  • sandBox源码分析之ClassLoader

    提起classLoader,就不由自主想起了java classLoader的双亲委派模型,那么到底什么是双亲委派...

  • 从类加载开始的JVM学习

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

  • SPI的ClassLoader问题

    问题 为什么说spi服务机制破坏了双亲委派模型? 双亲委派机制 启动类加载器(Bootstrap ClassLoa...

  • jvm双亲委派

    面试题: 1、什么是双亲委派?2、为什么需要双亲委派,不委派有什么问题?3、"父加载器"和"子加载器"之间的关系是...

  • 双亲委派模式

    看看下面这些问题,你能回答几个: 1、什么是双亲委派?2、为什么需要双亲委派,不委派有啥问题?3、“父加载器”和“...

  • 双亲委派

    JVM在加载类时默认采用的是双亲委派机制。 某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器...

  • 双亲委派

    为什么双亲委派?::原因:修改java.lang.String类并且通过自定义类加载器加入到JVM中,等于覆盖了 ...

  • 双亲委派

    转载Hollis,原文地址[https://mp.weixin.qq.com/s/Q0MqcvbeI7gAcJH5...

网友评论

      本文标题:常说的“双亲委派”中,双亲指的是什么?

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