天天看点

Tomcat源码分析——类加载体系前言概述源码分析

tomcat遵循j2ee规范,实现了web容器。很多有关web的书籍和文章都离不开对tomcat的分析,初学者可以从tomcat的实现对j2ee有更深入的了解。此外,tomcat还根据java虚拟机规范实现了经典的双亲委派模式的类加载体系。本文基于tomcat7.0的java源码,对其类加载体系进行分析。

首先简单介绍下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\testproj\classes helloworld。

appclass loader:加载system.getproperty("java.class.path")所指定的 路径或jar。在使用java运行程序时,也可以加上-cp来覆盖原有的classpath设置,例如: java -cp ./lavasoft/classes helloworld。

然后用一张图片来展示tomcat的类加载体系:

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方法的部分代码清单如下:

 我们接着来看initclassloaders方法的实现:

 创建类加载器的createclassloader方法的实现:

createclassloader最终使用classloaderfactory.createclassloader(locations, types, parent)方法创建classloader。我们回头看看securityclassload.securityclassload(catalinaloader)的实现:

securityclassload方法主要加载tomcat容器所需的class,包括:

tomcat核心class,即org.apache.catalina.core路径下的class;

org.apache.catalina.loader.webappclassloader$privilegedfindresourcebyname;

tomcat有关session的class,即org.apache.catalina.session路径下的class;

tomcat工具类的class,即org.apache.catalina.util路径下的class;

javax.servlet.http.cookie;

tomcat处理请求的class,即org.apache.catalina.connector路径下的class;

tomcat其它工具类的class,也是org.apache.catalina.util路径下的class;

我们以加载tomcat核心class的loadcorepackage方法为例,查看其实现:

 至此,我们还没有看到webappclassloader。启动standardcontext的时候会创建webapploader,standardcontext的方法startinternal的部分代码如下:

 从上面代码看到最后会调用webapploader的start方法,start又调用了startinternal方法,startinternal的实现如下:

 最后我们看看createclassloader的实现:

 至此,整个tomcat的类加载体系构建完毕。