Java虚拟机规范中提到的主要类加载器:
Bootstrap Loader:加载lib目录下或者System.getProperty(“sun.boot.class.path”)、或者-XBootclasspath所指定的路径或jar。
Extended Loader:加载lib\ext目录下或者System.getProperty(“java.ext.dirs”) 所指定的 路径或jar。在使用Java运行程序时,也可以指定其搜索路径,例如:java -Djava.ext.dirs=d:\projects\load\classes HelloWorld。
AppClassLoader:加载System.getProperty("java.class.path")所指定的 路径或jar。在使用Java运行程序时,也可以加上-cp来覆盖原有的Classpath设置,例如: java -cp ./load/classes HelloWorld
tomcat 实现了基于自身的类加载体系如下:
类加载体系进行介绍:
ClassLoader:Java提供的类加载器抽象类,用户自定义的类加载器需要继承实现;
commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被 Tomcat 容器本身以及各个Webapp访问;
catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见。
源码分析:
commonLoader、catalinaLoader和sharedLoader是在Tomcat容器初始化的的过程刚刚开始,即调用Bootstrap的init方法时创建的。catalinaLoader会被设置为Tomcat主线程的线程上下文类加载器,并且使用catalinaLoader加载Tomcat容器自身的class。Bootstrap的init方法的部分如代码清单1所示。
类加载器的执行步骤如下:
初始化commonLoader、catalinaLoader和sharedLoader;
将catalinaLoader设置为Tomcat主线程的线程上下文类加载器;
线程安全的加载class。
初始化类加载器分析:
initClassLoaders方法的实现如代码如下:
可以看到initClassLoaders调用createClassLoader方法来创建commonLoader、catalinaLoader和sharedLoader,我们来看看createClassLoader的实现;见如下代码:
createClassLoader的处理步骤如下:
定位资源路径与资源类型;
使用ClassLoaderFactory创建类加载器org.apache.catalina.loader.StandardClassLoader。
需要注意的是,Tomcat默认只会指定commonLoader(通过common属性,默认值为catalina.base/lib,catalina.base/lib,{catalina.base}/lib/*.jar,catalina.home/lib,catalina.home/lib,{catalina.home}/lib/*.jar),catalinaLoader和sharedLoader实际也是commonLoader。属性catalina.home默认为Tomcat的根目录。