标签:apache 不可 信息 不能 功能 socket nbsp java_home index
与很多服务器应用一样,Tomcat 也安装了各种类加载器(那就是实现了 java.lang.ClassLoader
的类)。借助类加载器,容器的不同部分以及运行在容器上的 Web 应用就可以访问不同的仓库(保存着可使用的类和资源)。这个机制实现了 Servlet 规范 2.4 版(尤其是 9.4 节和 9.6 节)里所定义的功能。
在 Java 环境中,类加载器的布局结构是一种父子树的形式。通常,类加载器被请求加载一个特定的类或资源时,它会先把这一请求委托给它的父类加载器,只有(一个或多个)父类加载器无法找到请求的类或资源时,它才开始查看自身的仓库。注意,Web 应用的类加载器模式跟这个稍有不同,下文将详细介绍,但基本原理是一样。
当 Tomcat 启动后,它就会创建一组类加载器,这些类加载器被布局成如下图所示这种父子关系,父类加载器在子类加载器之上:
Bootstrap
|
System
|
Common
/ Webapp1 Webapp2 ...
接下来,通过几节内容来详细说明每一个类加载器的特点,其中还将讲解这些加载器可使用的类和资源的来源。
如上图所示,Tomcat 在初始化时会创建如下这些类加载器:
Bootstrap 这种类加载器包含 JVM 所提供的基本的运行时类,以及来自系统扩展目录($JAVA_HOME/jre/lib/ext
)里 JAR 文件中的类。注意:在有些 JVM 的实现中,它的作用不仅仅是类加载器,或者它可能根本不可见(作为类加载器)。
System 这种类加载器通常是根据 CLASSPATH
环境变量内容进行初始化的。所有的这些类对于 Tomcat 内部类以及 Web 应用来说都是可见的。不过,标准的 Tomcat 启动脚本($CATALINA_HOME/bin/catalina.sh
或 %CATALINA_HOME%\bin\catalina.bat
)完全忽略了 CLASSPATH
环境变量自身的内容,相反从下列仓库来构建系统类加载器:
$CATALINA_HOME/bin/bootstrap.jar
包含用来初始化 Tomcat 服务器的 main()
方法,以及它所依赖的类加载器实现类。$CATALINA_BASE/bin/tomcat-juli.jar
或 $CATALINA_HOME/bin/tomcat-juli.jar
日志实现类。其中包括了对 java.util.logging
API 的功能增强类(Tomcat JULI),以及对 Tomcat 内部使用的 Apache Commons 日志库的包重命名副本。详情参看 Tomcat 日志文档。
如果 *$CATALINA_BASE/bin* 中存在 `tomcat-juli.jar`,就不会使用 *$CATALINA_HOME/bin* 中的那一个。它有助于日志的特定配置。
$CATALINA_HOME/bin/commons-daemon.jar
Apache Commons Daemon 项目的类。该 JAR 文件并不存在于由 catalina.bat
或 catalina.sh
脚本所创建的 CLASSPATH
中,而是引用自 bootstrap.jar 的清单文件。Common 这种类加载器包含更多的额外类,它们对于Tomcat 内部类以及所有 Web 应用都是可见的。
通常,应用类不会放在这里。该类加载器所搜索的位置定义在 $CATALINA_BASE/conf/catalina.properties
的 common.loader
属性中。默认的设置会搜索下列位置(按照列表中的上下顺序)。
$CATALINA_BASE/lib
中的解包的类和资源。$CATALINA_BASE/lib
中的 JAR 文件。$CATALINA_HOME/lib
中的解包类和资源。$CATALINA_HOME/lib
中的 JAR 文件。
默认,它包含以下这些内容:
/WEB-INF/classes
目录中所有的解包类及资源,以及 /WEB-INF/lib
目录下 JAR 文件中的所有类及资源,对于该应用而言都是可见的,但对于其他应用来说则不可见。如上所述,Web 应用类加载器背离了默认的 Java 委托模式(根据 Servlet 规范 2.4 版的 9.7.2 Web Application Classloader一节中提供的建议)。当某个请求想从 Web 应用的 WebappX 类加载器中加载类时,该类加载器会先查看自己的仓库,而不是预先进行委托处理。There are exceptions。JRE 基类的部分类不能被重写。对于一些类(比如 J2SE 1.4+ 的 XML 解析器组件),可以使用 J2SE 1.4 支持的特性。最后,类加载器会显式地忽略所有包含 Servlet API 类的 JAR 文件,所以不要在 Web 应用包含任何这样的 JAR 文件。Tomcat 其他的类加载器则遵循常用的委托模式。
因此,从 Web 应用的角度来看,加载类或资源时,要查看的仓库及其顺序如下:
/WEB-INF/classes
类/WEB-INF/lib/*.jar
类如果 Web 应用类加载器配置有 <Loader delegate="true"/>
,则顺序变为:
/WEB-INF/classes
类/WEB-INF/lib/*.jar
类从 Java 1.4 版起,JRE 就包含了一个 JAXP API 的副本和一个 XML 解析器。这对希望使用自己的 XML 解析器的应用产生了一定的影响。
在过去的 Tomcat 中,你只需在 Tomcat 库中简单地换掉 XML 解析器,就能改变所有 Web 应用使用的解析器。但对于现在版本的 Java 而言,这一技术并没有效果,因为通常的类加载器委托进程往往会优先选择 JDK 内部的实现。
Java 支持一种叫做“授权标准覆盖机制”,从而能够替换在 JCP 之外创建的 API(例如 W3C 的 DOM 和 SAX)。它还可以用于更新 XML 解析器实现。关于此机制的详情,请参看 http://docs.oracle.com/javase/1.5.0/docs/guide/standards/index.html。
为了利用该机制,Tomcat 在启动容器的命令行中包含了系统属性设置 -Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS
。该选项的默认值为 $CATALINA_HOME/endorsed
。但要注意,这个 endorsed
目录并非默认创建的。
当在安全管理器下运行时,类被允许加载的位置也是基于策略文件中的内容,详情可查看 安全管理器文档。
标签:apache 不可 信息 不能 功能 socket nbsp java_home index
原文地址:https://www.cnblogs.com/pingxin/p/p00054.html