zoukankan      html  css  js  c++  java
  • 分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系

    测试代码: 

     1 class Hello
     2 {
     3   public String str = "Hello World";
     4   public void fun()
     5   {
     6     System.out.println(str);
     7   }
     8 }
     9 
    10 public class Test{
    12   public static void main(String[] args)
    13   {
    14     Hello hello = new Hello();
    15     hello.fun();
    16 
    17     System.out.println("----------------------");
    18 
    19     //Hello类的类加载器
    20     ClassLoader classLoaderOfHello = Hello.class.getClassLoader();
    21 
    22     System.out.println("Hello is Loaded by : "+classLoaderOfHello);
    23 
    24     System.out.println("----------------------");
    25 
    26     //Hello类的类加载器的Class对象
    27     Class AppClazz = classLoaderOfHello.getClass();
    28 
    29     //分析Hello类的类加载器的Class对象的类继承关系
    30     while(AppClazz != null)
    31     {
    32     System.out.println(AppClazz);
    33 
    34     AppClazz = AppClazz.getSuperclass();
    35     }
    36 
    37     System.out.println("----------------------");
    38 
    39     //取得扩展器加载器的类对象Class
    40     Class ExtClazz = classLoaderOfHello.getParent().getClass();
    41 
    42     while(ExtClazz != null)
    43     {
    44     System.out.println(ExtClazz);
    45 
    46     ExtClazz = ExtClazz.getSuperclass();
    47     }
    48   }
    49 }
    50 
    51  

    结论:

    1.  用户自定义的类是由 应用(系统)类加载器AppClassLoader加载

    2.  在”父亲委托机制”中,扩展类加载器ExtClassLoader是AppClassLoader的父亲,并不是继承关系,而是ExtClassLoader加载了AppClassLoader

    3.  AppClassLoader 和 ExtClassLoader 都扩展于 URLClassLoader加载器.

    4.  也同时说明AppClassLoader而非继承ExtClassLoader.

    继承关系:

    java.lang.Object

           --- java.lang.ClassLoader
                  --- java.security.SecureClassLoader
                          ---  java.net.URLClassLoader
                                --- sun.misc.Launcher$ExtClassLoader

    java.lang.Object

           --- java.lang.ClassLoader
                  --- java.security.SecureClassLoader
                          ---  java.net.URLClassLoader
                                --- sun.misc.Launcher$AppClassLoader

    其实很简单嘛,直接看AppClassLoader的源代码就可以了嘛,哈哈,终于找到了好东东,上

    JDK7: http://download.java.net/openjdk/jdk7/

    JDK6: http://download.java.net/openjdk/jdk6/

    下载其源代码就可以了


    现在直接来看其源代码:


    /**
    * The class loader used for loading from java.class.path.
    * runs in a restricted security context.
    */
    static class AppClassLoader extends URLClassLoader {

    static {
    ClassLoader.registerAsParallelCapable();
    }

    public static ClassLoader getAppClassLoader(final ClassLoader extcl)
    throws IOException
    {
    final String s = System.getProperty("java.class.path");
    final File[] path = (s == null) ? new File[0] : getClassPath(s);


    return AccessController.doPrivileged(
    new PrivilegedAction<AppClassLoader>() {
    public AppClassLoader run() {
    URL[] urls =
    (s == null) ? new URL[0] : pathToURLs(path);
    return new AppClassLoader(urls, extcl);
    }
    });
    }

    /*
    * Creates a new AppClassLoader
    */
    AppClassLoader(URL[] urls, ClassLoader parent) {
    super(urls, parent, factory);
    }

    /**
    * Override loadClass so we can checkPackageAccess.
    */
    public Class loadClass(String name, boolean resolve)
    throws ClassNotFoundException
    {
    int i = name.lastIndexOf('.');
    if (i != -1) {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
    sm.checkPackageAccess(name.substring(0, i));
    }
    }
    return (super.loadClass(name, resolve));
    }

    /**
    * allow any classes loaded from classpath to exit the VM.
    */
    protected PermissionCollection getPermissions(CodeSource codesource)
    {
    PermissionCollection perms = super.getPermissions(codesource);
    perms.add(new RuntimePermission("exitVM"));
    return perms;
    }

    /**
    * This class loader supports dynamic additions to the class path
    * at runtime.
    *
    * @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch
    */
    private void appendToClassPathForInstrumentation(String path) {
    assert(Thread.holdsLock(this));

    // addURL is a no-op if path already contains the URL
    super.addURL( getFileURL(new File(path)) );
    }

    /**
    * create a context that can read any directories (recursively)
    * mentioned in the class path. In the case of a jar, it has to
    * be the directory containing the jar, not just the jar, as jar
    * files might refer to other jar files.
    */

    private static AccessControlContext getContext(File[] cp)
    throws java.net.MalformedURLException
    {
    PathPermissions perms =
    new PathPermissions(cp);

    ProtectionDomain domain =
    new ProtectionDomain(new CodeSource(perms.getCodeBase(),
    (java.security.cert.Certificate[]) null),
    perms);

    AccessControlContext acc =
    new AccessControlContext(new ProtectionDomain[] { domain });

    return acc;
    }
    }

    哈,看了AppClassLoader的源代码后,大家明白了吧,AppClassLoader 继承了URLClassLoader,而且构造函数是直接调用URLClassLoader的构造

    函数,loadClass(String name, boolean resolve)方法只是简单做了包的安全检查,然后就调用ClassLoader的 loadClass(String name, boolean resolve)方法了,其它的话,也是差不多..所以其功能和URLClassLoader差不多...

    在ExtClassLoader也差不多,大家看看源代码就明了的:

    /*
    * Creates a new ExtClassLoader for the specified directories.
    */
    public ExtClassLoader(File[] dirs) throws IOException {
    super(getExtURLs(dirs), null, factory);
    }

    private static File[] getExtDirs() {
    String s = System.getProperty("java.ext.dirs");
    File[] dirs;
    if (s != null) {
    StringTokenizer st =
    new StringTokenizer(s, File.pathSeparator);
    int count = st.countTokens();
    dirs = new File[count];
    for (int i = 0; i < count; i++) {
    dirs[i] = new File(st.nextToken());
    }
    } else {
    dirs = new File[0];
    }
    return dirs;
    }

    private static URL[] getExtURLs(File[] dirs) throws IOException {
    Vector<URL> urls = new Vector<URL>();
    for (int i = 0; i < dirs.length; i++) {
    String[] files = dirs[i].list();
    if (files != null) {
    for (int j = 0; j < files.length; j++) {
    if (!files[j].equals("meta-index")) {
    File f = new File(dirs[i], files[j]);
    urls.add(getFileURL(f));
    }
    }
    }
    }
    URL[] ua = new URL[urls.size()];
    urls.copyInto(ua);
    return ua;
    }

    /*
    * Searches the installed extension directories for the specified
    * library name. For each extension directory, we first look for
    * the native library in the subdirectory whose name is the value
    * of the system property <code>os.arch</code>. Failing that, we
    * look in the extension directory itself.
    */
    public String findLibrary(String name) {
    name = System.mapLibraryName(name);
    URL[] urls = super.getURLs();
    File prevDir = null;
    for (int i = 0; i < urls.length; i++) {
    // Get the ext directory from the URL
    File dir = new File(urls[i].getPath()).getParentFile();
    if (dir != null && !dir.equals(prevDir)) {
    // Look in architecture-specific subdirectory first
    // Read from the saved system properties to avoid deadlock
    String arch = VM.getSavedProperty("os.arch");
    if (arch != null) {
    File file = new File(new File(dir, arch), name);
    if (file.exists()) {
    return file.getAbsolutePath();
    }
    }
    // Then check the extension directory
    File file = new File(dir, name);
    if (file.exists()) {
    return file.getAbsolutePath();
    }
    }
    prevDir = dir;
    }
    return null;
    }

    private static AccessControlContext getContext(File[] dirs)
    throws IOException
    {
    PathPermissions perms =
    new PathPermissions(dirs);

    ProtectionDomain domain = new ProtectionDomain(
    new CodeSource(perms.getCodeBase(),
    (java.security.cert.Certificate[]) null),
    perms);

    AccessControlContext acc =
    new AccessControlContext(new ProtectionDomain[] { domain });

    return acc;
    }
    }

    ---------------------
    作者:irelandken
    来源:CSDN
    原文:https://blog.csdn.net/irelandken/article/details/7046689
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    单服务器高性能模式:Reactor 与Proactor
    大数据加工平台二_系统说明
    大数据加工平台py文件内容
    大数据竞赛练习题五
    大数据加工平台面向对象说明一
    大数据加工平台一
    大数据加工平台面向对象说明二
    大数据加工平台三
    大数据竞赛练习题六
    大数据竞赛练习题四
  • 原文地址:https://www.cnblogs.com/makai/p/11080430.html
Copyright © 2011-2022 走看看