分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系

分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系

分类: JAVA_WEB   133人阅读  评论(0)  收藏  举报

分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系


测试代码: 

[java]  view plain copy
  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  
  11. {  
  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. }  




结论:

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

2.  在”父亲委托机制”中,扩展类加载器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/

下载其源代码就可以了

现在直接来看其源代码:


[java]  view plain copy
  1. /** 
  2.      * The class loader used for loading from java.class.path. 
  3.      * runs in a restricted security context. 
  4.      */  
  5.     static class AppClassLoader extends URLClassLoader {  
  6.   
  7.         static {  
  8.             ClassLoader.registerAsParallelCapable();  
  9.         }  
  10.   
  11.         public static ClassLoader getAppClassLoader(final ClassLoader extcl)  
  12.             throws IOException  
  13.         {  
  14.             final String s = System.getProperty("java.class.path");  
  15.             final File[] path = (s == null) ? new File[0] : getClassPath(s);  
  16.   
  17.             
  18.             return AccessController.doPrivileged(  
  19.                 new PrivilegedAction<AppClassLoader>() {  
  20.                     public AppClassLoader run() {  
  21.                     URL[] urls =  
  22.                         (s == null) ? new URL[0] : pathToURLs(path);  
  23.                     return new AppClassLoader(urls, extcl);  
  24.                 }  
  25.             });  
  26.         }  
  27.   
  28.         /* 
  29.          * Creates a new AppClassLoader 
  30.          */  
  31.         AppClassLoader(URL[] urls, ClassLoader parent) {  
  32.             super(urls, parent, factory);  
  33.         }  
  34.   
  35.         /** 
  36.          * Override loadClass so we can checkPackageAccess. 
  37.          */  
  38.         public Class loadClass(String name, boolean resolve)  
  39.             throws ClassNotFoundException  
  40.         {  
  41.             int i = name.lastIndexOf('.');  
  42.             if (i != -1) {  
  43.                 SecurityManager sm = System.getSecurityManager();  
  44.                 if (sm != null) {  
  45.                     sm.checkPackageAccess(name.substring(0, i));  
  46.                 }  
  47.             }  
  48.             return (super.loadClass(name, resolve));  
  49.         }  
  50.   
  51.         /** 
  52.          * allow any classes loaded from classpath to exit the VM. 
  53.          */  
  54.         protected PermissionCollection getPermissions(CodeSource codesource)  
  55.         {  
  56.             PermissionCollection perms = super.getPermissions(codesource);  
  57.             perms.add(new RuntimePermission("exitVM"));  
  58.             return perms;  
  59.         }  
  60.   
  61.         /** 
  62.          * This class loader supports dynamic additions to the class path 
  63.          * at runtime. 
  64.          * 
  65.          * @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch 
  66.          */  
  67.         private void appendToClassPathForInstrumentation(String path) {  
  68.             assert(Thread.holdsLock(this));  
  69.   
  70.             // addURL is a no-op if path already contains the URL  
  71.             super.addURL( getFileURL(new File(path)) );  
  72.         }  
  73.   
  74.         /** 
  75.          * create a context that can read any directories (recursively) 
  76.          * mentioned in the class path. In the case of a jar, it has to 
  77.          * be the directory containing the jar, not just the jar, as jar 
  78.          * files might refer to other jar files. 
  79.          */  
  80.   
  81.         private static AccessControlContext getContext(File[] cp)  
  82.             throws java.net.MalformedURLException  
  83.         {  
  84.             PathPermissions perms =  
  85.                 new PathPermissions(cp);  
  86.   
  87.             ProtectionDomain domain =  
  88.                 new ProtectionDomain(new CodeSource(perms.getCodeBase(),  
  89.                     (java.security.cert.Certificate[]) null),  
  90.                 perms);  
  91.   
  92.             AccessControlContext acc =  
  93.                 new AccessControlContext(new ProtectionDomain[] { domain });  
  94.   
  95.             return acc;  
  96.         }  
  97.     }  

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

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


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

[java]  view plain copy
  1. /* 
  2.        * Creates a new ExtClassLoader for the specified directories. 
  3.        */  
  4.       public ExtClassLoader(File[] dirs) throws IOException {  
  5.           super(getExtURLs(dirs), null, factory);  
  6.       }  
  7.   
  8.       private static File[] getExtDirs() {  
  9.           String s = System.getProperty("java.ext.dirs");  
  10.           File[] dirs;  
  11.           if (s != null) {  
  12.               StringTokenizer st =  
  13.                   new StringTokenizer(s, File.pathSeparator);  
  14.               int count = st.countTokens();  
  15.               dirs = new File[count];  
  16.               for (int i = 0; i < count; i++) {  
  17.                   dirs[i] = new File(st.nextToken());  
  18.               }  
  19.           } else {  
  20.               dirs = new File[0];  
  21.           }  
  22.           return dirs;  
  23.       }  
  24.   
  25.       private static URL[] getExtURLs(File[] dirs) throws IOException {  
  26.           Vector<URL> urls = new Vector<URL>();  
  27.           for (int i = 0; i < dirs.length; i++) {  
  28.               String[] files = dirs[i].list();  
  29.               if (files != null) {  
  30.                   for (int j = 0; j < files.length; j++) {  
  31.                       if (!files[j].equals("meta-index")) {  
  32.                           File f = new File(dirs[i], files[j]);  
  33.                           urls.add(getFileURL(f));  
  34.                       }  
  35.                   }  
  36.               }  
  37.           }  
  38.           URL[] ua = new URL[urls.size()];  
  39.           urls.copyInto(ua);  
  40.           return ua;  
  41.       }  
  42.   
  43.       /* 
  44.        * Searches the installed extension directories for the specified 
  45.        * library name. For each extension directory, we first look for 
  46.        * the native library in the subdirectory whose name is the value 
  47.        * of the system property <code>os.arch</code>. Failing that, we 
  48.        * look in the extension directory itself. 
  49.        */  
  50.       public String findLibrary(String name) {  
  51.           name = System.mapLibraryName(name);  
  52.           URL[] urls = super.getURLs();  
  53.           File prevDir = null;  
  54.           for (int i = 0; i < urls.length; i++) {  
  55.               // Get the ext directory from the URL  
  56.               File dir = new File(urls[i].getPath()).getParentFile();  
  57.               if (dir != null && !dir.equals(prevDir)) {  
  58.                   // Look in architecture-specific subdirectory first  
  59.                   // Read from the saved system properties to avoid deadlock  
  60.                   String arch = VM.getSavedProperty("os.arch");  
  61.                   if (arch != null) {  
  62.                       File file = new File(new File(dir, arch), name);  
  63.                       if (file.exists()) {  
  64.                           return file.getAbsolutePath();  
  65.                       }  
  66.                   }  
  67.                   // Then check the extension directory  
  68.                   File file = new File(dir, name);  
  69.                   if (file.exists()) {  
  70.                       return file.getAbsolutePath();  
  71.                   }  
  72.               }  
  73.               prevDir = dir;  
  74.           }  
  75.           return null;  
  76.       }  
  77.   
  78.       private static AccessControlContext getContext(File[] dirs)  
  79.           throws IOException  
  80.       {  
  81.           PathPermissions perms =  
  82.               new PathPermissions(dirs);  
  83.   
  84.           ProtectionDomain domain = new ProtectionDomain(  
  85.               new CodeSource(perms.getCodeBase(),  
  86.                   (java.security.cert.Certificate[]) null),  
  87.               perms);  
  88.   
  89.           AccessControlContext acc =  
  90.               new AccessControlContext(new ProtectionDomain[] { domain });  
  91.   
  92.           return acc;  
  93.       }  
  94.   }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值