所有的类加载器都继承自java.lang.ClassLoader。
在java环境中,类加载器是按父子节点安排的。通常情况下,某个类加载器被请求加载某个类或资源时,首先是把这个请求反馈给父的类加载器,让父的类加载器去寻找;如果父的加载器没有找到然后才是自己找。
Web应用程序的类加载器则与java环境中的加载过程有点不同。以Tomcat为例:
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
Bootstrap
Bootstrap类加载器包含JVM中的运行时类、$JAVA_HOME/jre/lib/ext中的所有JAR文件。
System
System类加载器包含是从CLASSPATH环境变量指定的地址中找到的类。这些类包括Tomcat的内部类。
Common
这个类加载器包含其它的类,这些类可以被Tomcat内部类和所有web应用程序访问。
这个类加载器默认搜索的地方由$CATALINA_BASE/conf/catalina.properties文件中的commn.loader属性定义,默认的设置是:
- unpackedclasses and resources in $CATALINA_BASE/lib
- JARfiles in $CATALINA_BASE/lib
- unpackedclasses and resources in $CATALINA_HOME/lib
- JARfiles in $CATALINA_HOME/lib
WebappX
每个部署到Tomcat的应用程序都会有一个类加载器,加载的内容包括:/WEB-INF/classes、/WEB-INF/lib/*.jar。
Web类加载器与Java环境中的类加载器不同的地方
当需要使用WebappX类加载器加载资源时,首先寻找是WebappX中能找到的资源,而不是向父的类加载器委托。只有这一步不同,再往上还是一样的。
但有以下几个例外或需要注意:
- JRE的基类不能被覆盖;
- 任何包含ServletAPI classes的JAR文件都会被这个类加载器忽略,所以不要在应用程序中包含这类JAR文件(影响性能)。
Tomcat的类加载顺序
综上所述,在Tomcat中类和资源的搜索顺序如下:
- Bootstrap classes of your JVM
- System class loader classes
- /WEB-INF/classes of your web application
- /WEB-INF/lib/*.jar of your webapplication
- Common class loader classes