分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系

分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系


测试代码:

class Hello { public String str = "Hello World"; public void fun() { System.out.println(str); } } public class Test { public static void main(String[] args) { Hello hello = new Hello(); hello.fun(); System.out.println("----------------------"); //Hello类的类加载器 ClassLoader classLoaderOfHello = Hello.class.getClassLoader(); System.out.println("Hello is Loaded by : "+classLoaderOfHello); System.out.println("----------------------"); //Hello类的类加载器的Class对象 Class AppClazz = classLoaderOfHello.getClass(); //分析Hello类的类加载器的Class对象的类继承关系 while(AppClazz != null) { System.out.println(AppClazz); AppClazz = AppClazz.getSuperclass(); } System.out.println("----------------------"); //取得扩展器加载器的类对象Class Class ExtClazz = classLoaderOfHello.getParent().getClass(); while(ExtClazz != null) { System.out.println(ExtClazz); ExtClazz = ExtClazz.getSuperclass(); } } }



结论:

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/

下载其源代码就可以了

现在直接来看其源代码:


/** * 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; } }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值