首页 > 代码库 > [译]Tomcat8类加载机制

[译]Tomcat8类加载机制

原文直通车:Class Loader HOW-TO

 

目录

  • 概述
  • 类加载器的定义
  • XML解析器和Java
  • 运行在security manager下

概述

  和其他服务器程序类似,Tomcat也定义了一些类加载器(实现了java.lang.ClassLoader的类)用以实现让Tomcat的容器的不同部分、运行

在tomcat容器里的web应用都有各自不同的类和资源的加载路径。该机制用以提供Servlet2.4规范的第9.4章和9.6章的所规定的功能。

  在Java环境下,类加载器被组织成了父-子树状的结构。一般情况下,让一个类加载器要加载一个类或者资源的时候,该加载器首先询问自己

的父加载其能否加载该类,依次询问到树根节点,只有当所有的父加载器都不能加载该类的时候,该加载器才会尝试加载该类。但是web应用

的类加载机制跟传统的java类加载机制有少许的不同,我们下面会进行介绍,但是总体的原则是一样的。

  Tomcat在启动的时候会创建一系列的类加载器,这些类加载器被组织成下图所示的父-子树状结构,父加载器,子类加载器在下:

      Bootstrap          |       System          |       Common       /       Webapp1   Webapp2 ...

  下面我们就讨论上述每个类加载器的特质以及他们锁加载的资源和类的加载路径的位置。

类加载器的定义

  正如上图提到的那样,Tomcat在初始化的时候就会创建如下类加载器:

  • Bootstrap类加载器 : 该类加载器会加载JVM提供的基本的java运行时所依赖的类,而且还会加载JAVA_HOME/jre/lib/ext目录下的所有的类。
    注意:不同的JVM实现方式可能会有不同,比如有些JVM实现的时候会把Bootstrap类加载器实现的功能分成两个类加载器来实现(一般把它们
    称为bootstrap类加载器和Extenstion类加载器);或者有些JVM的实现中干脆没有定义bootstrap类加载器(内置实现)

 

  • System类加载器:一般情况下这个类加载器是从CLASSPATH环境变量来加载类和资源。该类加载器中所加载的类是可以被Tomcat的中的类或
    者web应用中的类使用。但是Tomcat的启动脚本(位于$CATALINA_HOME/bin/catalina.sh或者$CATALINA_HOME/bin/catalina.bat)完全
    忽视CLASSPATH环境变量所指定的类加载路径。最终Tomcat会把该类加载器的的加载路径设置为如下几个
    1. $CATALINA_HOME/bin/bootstrap.jar --该jar文件包含一个main()方法用以初始化Tomcat服务器和Tomcat所用的类加载的实现类
    2. $CATALINA_HOME/bin/tomcat-juli.jar或者$CATALINA_BASE/bin/tomcat-juli.jar--日志实现包。这个jar包的主要作用是包含了增强
       的java.util.logging API的实现,也被称为Tomcat Juli。还包括了一个被重命名的Apache Commons Logging的依赖库
       如果tomcat-juli.jar在$CATALINA_BASE/bin和$CATALINA_HOME/bin都出现的话优先使用$CATALINA_BASE/bin下所指定的。这个特性可
       一用来定制Tomcat实例的日志特性
    3. $CATALINA_HOME/bin/commons-daemon.jar – 这个jar包里面的class都是出自Apache Commons Daemon项目。这个jar包在catalina.bat
        或者catalina.sh脚本中并没有加到CLASSPATH中,但是这个jar包在bootstrap.jar的mainnifest文件中有对他的引用。

 

  • Common类加载器:--该类加载器所加载的类对Tomcat的内部类和web应用的都是可见的
      一般情况下,web应用的class文件最好不要放到这里。该类加载的加载类的路径是在$CATALINA_BASE/conf/catalina.properties文件中的
    common.loader属性所指定。不人为指定的话默认配置会搜索如下路径:
    1. $CATALINA_BASE/lib下的没有打包的class或者resources文件
    2. $CATALINA_BASE/lib下的jar文件
    3. $CATALINA_HOME/lib下的所有打包的class或者resources文件
    4. $CATALINA_HOME/lib下的jar文件

    默认情况下,改加载路径下有如下jar包