分析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("----------------------");
-
-
- ClassLoader classLoaderOfHello = Hello.class.getClassLoader();
-
- System.out.println("Hello is Loaded by : "+classLoaderOfHello);
-
- System.out.println("----------------------");
-
-
- Class AppClazz = classLoaderOfHello.getClass();
-
-
- while(AppClazz != null)
- {
- System.out.println(AppClazz);
-
- AppClazz = AppClazz.getSuperclass();
- }
-
- System.out.println("----------------------");
-
-
- 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/
下载其源代码就可以了
现在直接来看其源代码:
-
-
-
-
- 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);
- }
- });
- }
-
-
-
-
- AppClassLoader(URL[] urls, ClassLoader parent) {
- super(urls, parent, factory);
- }
-
-
-
-
- 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));
- }
-
-
-
-
- protected PermissionCollection getPermissions(CodeSource codesource)
- {
- PermissionCollection perms = super.getPermissions(codesource);
- perms.add(new RuntimePermission("exitVM"));
- return perms;
- }
-
-
-
-
-
-
-
- private void appendToClassPathForInstrumentation(String path) {
- assert(Thread.holdsLock(this));
-
-
- super.addURL( getFileURL(new File(path)) );
- }
-
-
-
-
-
-
-
-
- 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也差不多,大家看看源代码就明了的:
-
-
-
- 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;
- }
-
-
-
-
-
-
-
-
- public String findLibrary(String name) {
- name = System.mapLibraryName(name);
- URL[] urls = super.getURLs();
- File prevDir = null;
- for (int i = 0; i < urls.length; i++) {
-
- File dir = new File(urls[i].getPath()).getParentFile();
- if (dir != null && !dir.equals(prevDir)) {
-
-
- String arch = VM.getSavedProperty("os.arch");
- if (arch != null) {
- File file = new File(new File(dir, arch), name);
- if (file.exists()) {
- return file.getAbsolutePath();
- }
- }
-
- 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;
- }
- }