Java ClassLoader加载机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java ClassLoader加载机制相关的知识,希望对你有一定的参考价值。
一.体系结构(自上向下)
1.Bootstrap ClassLoader(BootStrapClassLoader) --- 启动类加载器或者叫引导类加载器,加载jdk核心的APIs,这些APIs一般位于jdk_home/lib下;它是一个本地接口,所以不能从java代码中得到它的信息。例如, log(java.lang.String.class.getClassLoader())得到的是null。
2.Extension ClassLoader(Launcher$ExtClassLoader) --- 扩展类加载器, 负责加载jdk_home/lib/ext目录下的API;
3.System ClassLoader(Launcher$AppClassLoader) --- 系统类加载器 主要负责java -classpath所指的目录下的APIs。
4.Custom ClassLoader --- 用户自定义类加载器,是java.lang.ClassLoader的子类),负责在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件。
二.加载机制
Java的ClassLoader是以父子结构展现的。当有请求向加载器请求类时,首先自底向上去寻找是否已经加载了所需的类,如果存在就返回这个类;如果不存在,就委托当前加载器的父加载器去完成加载类的请求,如果父加载器还有上一级,就向上一级的记载器请求去加载所需类,直到顶层,若顶层加载器(BootStrapClassLoader)无法加载类,就回到下一级,如果下一级仍无法加载,再下一级,直到当前的类加载器,如果仍加载不到,就会抛出ClassNotFoundExceptio。 注意:这里的父子关系不是java中的继承关系,可以理解为一种委托关系。
三.类的唯一标识
JVM中,类的唯一标识是(类名,包名,加载器),由不同加载器加载的类,即使具有相同的类名和包名,也不会被认为是同一个实例,不是类型可比型的。例如:ClassLoader A 有两个子加载器ClassLoader B 和 ClassLoader C,类Foo对ClassLoaderB和ClassLoaderC是可见的,对ClassLoaderA是不可见的,当有请求向ClassLoaderB和ClassLoaderC请求Foo的实例时,由于两个加载器会分别加载Foo,这样JVM会产生两个Foo的实例(foo1,foo2),而且它们是不可比的, 语句foo1=(Foo)foo2会抛出ClassCastException;当然,如果Foo对ClassLoaderA是可见的,Foo就会由ClassLoaderA加载,就不会产生ClassCastException了。
四.Servelet容器中类加载器
在Tomat5中简单做了个测试,发现Thread.currentThread().getContextClassLoader()得到的是如下的结果:
webapp classloader:WebappClassLoader
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
[email protected]
按照“Servlet Specification, version 2.3, section 9.7.2 Web Application Classloader”说法,通过WebappClassLoader应该能够加载任何库文件中的资源,但是不能覆盖J2SE和servlet APIs;将来值得推荐的做法servlet的加载器不允许servlet去访问web容器的实现类。
这里,摘录了官网上的Tomcat5和Tomcat6类加载的顺序:
Tomcat 5:
Bootstrap classes of your JVM
System class loader classes
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
$CATALINA_HOME/common/classes
$CATALINA_HOME/common/endorsed/*.jar
$CATALINA_HOME/common/i18n/*.jar
$CATALINA_HOME/common/lib/*.jar
$CATALINA_BASE/shared/classes
$CATALINA_BASE/shared/lib/*.jar
Tomcat 6:
Bootstrap classes of your JVM
System class loader classes
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
$CATALINA_HOME/lib
$CATALINA_HOME/lib/*.jar
以上是关于Java ClassLoader加载机制的主要内容,如果未能解决你的问题,请参考以下文章