码迷,mamicode.com
首页 > 编程语言 > 详细

浅析java类加载器ClassLoader

时间:2014-07-16 16:48:03      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   java   color   使用   

作为一枚java猿,了解类加载器是有必要的,无论是针对面试还是自我学习。

本文从JDK提供的ClassLoader、委托模型以及如何编写自定义的ClassLoader三方面对ClassLoader做一个简要的总结。

 

JDK中提供的ClassLoader

1. Bootstrap ClassLoader

  Bootstrap加载器是用C++语言写的,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib以及%JAVA_HOME%/jre/classes中的类,是最顶级的ClassLoader。

2. Ext ClassLoader

  Ext ClassLoader是用java写的,且它的父加载器是Bootstrap,具体来说就是sun.misc.Launcher$ExtClassLoader,Ext ClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中的类库。

3. App ClassLoader 

  系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。它的父加载器为Ext ClassLoader。

 

具体关系如下图:

bubuko.com,布布扣

委托模型

进入官方的Java doc里看到ClassLoader类的一段说明:

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine‘s built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.

ClassLoader类使用一种委托模型来查找类和资源。每个ClassLoader实例都会关联1个父ClassLoader。当需要查询类和资源的时候,一个ClassLoader实例在查询类或资源之前会先委托给它的父ClassLoader去查询。Bootstrap ClassLoader是最顶层的加载器,并且可以作为其它ClassLoader实例的父ClassLoader。

由此看见,这个“委托模型”的安全性是很高的,Bootstrap是最顶层的加载器,这样比如加载 java.lang.String 的时候,永远都会被Bootstrap加载(Bootstrap ClassLoader会加载%JAVA_HOME%/jre/lib中rt.jar里的String类)。 这样用户自定义的java.lang.String永远都不会被加载,这样就避免了多个java.lang.String造成的混乱现象。

 

下面通过jdk里的ClassLoader源码来验证一下查找过程:

  protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException
    {
	// First, check if the class has already been loaded
	Class c = findLoadedClass(name); //先查找这个类是否已经加载过,每个加载器都有自己的缓存
	if (c == null) {
	    try {
		if (parent != null) { //父加载器存在的话先使用父加载器加载
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClassOrNull(name); //没有父加载器的话使用bootstrap加载
		}
	    } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }
            if (c == null) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name); //如果父加载器没有找到,那么自身查找
	    }
	}
	if (resolve) {
	    resolveClass(c);
	}
	return c;
    }

通过代码看,这里的查找过程符合委托模型。

如何编写自定义的ClassLoader

编写自定义的ClassLoader注意2点即可:

1. 想遵循委托模型的话重写findClass方法即可。

2. 不遵循委托模型的话重写loadClass。

 

其他:defineClass方法把字节数组b中的内容转换成Java 类,返回的结果是 java.lang.Class类的实例。这个方法被声明为final的。该方法也是jvm预留给我们处理ClassLoader与类文件关系的入口。

    protected final Class<?> defineClass(String name, byte[] b, int off, int len)
    throws ClassFormatError

参考资料

http://imtiger.net/blog/2009/11/09/java-classloader/

http://www.ibm.com/developerworks/cn/java/j-lo-classloader/

http://jiangbo.me/blog/2012/02/14/jetty-classloader/

浅析java类加载器ClassLoader,布布扣,bubuko.com

浅析java类加载器ClassLoader

标签:style   blog   http   java   color   使用   

原文地址:http://www.cnblogs.com/fangjian0423/p/java-classloader.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!