Tomcat的类载入器以及源码分析.doc_第1页
Tomcat的类载入器以及源码分析.doc_第2页
Tomcat的类载入器以及源码分析.doc_第3页
Tomcat的类载入器以及源码分析.doc_第4页
Tomcat的类载入器以及源码分析.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Tomcat 的类载入器(Class Loader)2 Tomcat的类载入器(ClassLoader)(a) ClassLoader的结构Tomcat Server在启动的时候将构造一个ClassLoader树,以保证模块的类库是私有的。Tomcat Server的ClassLoader结构如下: +-+ | Bootstrap | | | | | System | | | | | Common | | / | | Catalina Shared | | / | | WebApp1 WebApp2 | +-+其中:- Bootstrap - 载入JVM自带的类和$JAVA_HOME/jre/lib/ext/*.jar- System - 载入$CLASSPATH/*.class- Common - 载入$CATALINA_HOME/common/.,它们对TOMCAT和所有的WEB APP都可见- Catalina - 载入$CATALINA_HOME/server/.,它们仅对TOMCAT可见,对所有的WEB APP都不可见- Shared - 载入$CATALINA_HOME/shared/.,它们仅对所有WEB APP可见,对TOMCAT不可见(也不必见)- WebApp - 载入ContextBase?/WEB-INF/.,它们仅对该WEB APP可见 (b) ClassLoader的原理每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类。系统默认的contextClassLoader是systemClassLoader,所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类可以使用Thread.currentThread().setContextClassLoader(.);更改当前线程的contextClassLoader,来改变其载入类的行为。ClassLoader被组织成树形,一般的工作原理是:1) 线程需要用到某个类,于是contextClassLoader被请求来载入该类。2) contextClassLoader请求它的父ClassLoader来完成该载入请求。3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入。注意:WebAppClassLoader的工作原理和上述有少许不同:它先试图自己载入类(在ContextBase/WEB-INF/.中载入类),如果无法载入,再请求父ClassLoader完成,由此可得:- 对于WEB APP线程,它的contextClassLoader是WebAppClassLoader- 对于Tomcat Server线程,它的contextClassLoader是CatalinaClassLoader。3 源码分析:(a) class Bootstrappackage org.apache.catalina.startup;/ JDK类库import java.io.File;import java.io.IOException;import java.lang.reflect.Method;import .MalformedURLException;import .URL;import java.util.ArrayList;/ apache自己的类库import org.apache.catalina.loader.Extension;import org.apache.catalina.loader.StandardClassLoader;/* * Boostrap loader for Catalina. This application constructs a class loader * for use in loading the Catalina internal classes (by accumulating all of the * JAR files found in the server directory under catalina.home), and * starts the regular execution of the container. The purpose of this * roundabout approach is to keep the Catalina internal classes (and any * other classes they depend on, such as an XML parser) out of the system * class path and therefore not visible to application level classes. * * author Craig R. McClanahan * version $Revision: 1.36 $ $Date: 2002/04/01 19:51:31 $ */* * 该类的main方法的主要任务: * - * * 1,创建TOMCAT自己的类载入器(ClassLoader) * +-+ * | Bootstrap | * | | | * | System | * | | | * | Common | * | / | * | Catalina Shared | * +-+ * 其中: * - Bootstrap - 载入JVM自带的类和$JAVA_HOME/jre/lib/ext/*.jar * - System - 载入$CLASSPATH/*.class * - Common - 载入$CATALINA_HOME/common/.,它们对TOMCAT和所有的WEB APP都可见 * - Catalina - 载入$CATALINA_HOME/server/.,它们仅对TOMCAT可见,对所有的WEB APP都不可见 * - Shared - 载入$CATALINA_HOME/shared/.,它们仅对所有WEB APP可见,对TOMCAT不可见(也不必见) * 注意:当一个ClassLoader被请求载入一个类时,它首先请求其父ClassLoader完成载入, * 仅当其父ClassLoader无法载入该类时,才试图自己载入该类 * 2,改变本身线程的默认ClassLoader(本线程就是Tomcat Server线程,类载入器是catalinaLoader) * 3,让catalinaLoader载入一些类,类的位置在$CATALINA_HOME/server/lib/catalina.jar中 * 4,创建org.apache.catalina.startup.Catalina类的一个实例startupInstance,并为其调用方法: * startupInstance.setParentClassLoader(sharedLoader); * startupIcess(args); * * * 有关ClassLoader的说明: * - * * 每个被DEPLOY的WEB APP都会被创建一个ClassLoader,用来载入该WEB APP自己的类 * 这些类的位置是webappX/WEB-INF/classes/*.class和webappX/WEB-INF/lib/*.jar * * ClassLoader的工作流程是: * 1) 收到一个载入类的的请求 * 2) 请求其父ClassLoader来完成该类的载入 * 3) 如果父ClassLoader无法载入,则自己试图完成该类的载入 * * 特别注意WEB APP自己的ClassLoader的实现与众不同: * 它先试图从WEB APP自己的目录里载入,如果失败则请求父ClassLoader的代理 * 这样可以让不同的WEB APP之间的类载入互不干扰 * * WEB APP的ClassLoader的层次结构是: * +-+ * | Shared | * | / . | * | Webapp1 Webapp2 . | * +-+ * 故对于一个WEB APP,其类载入的优先顺序如下: * - /WEB-INF/classes/*.class 和 /WEB-INF/lib/*.jar * - Bootstrap classes of JVM * - System class loader classes * - $CATALINA_HOME/common/. * - $CATALINA_HOME/shared/. * * * 小结: * - * * 综上分析 * - Tomcat Server线程使用的classLoader是Catalina * - 每个WEB APP线程使用的classloader是Webapp * */public final class Bootstrap /* * DEBUG级别 */ private static int debug = 0; /* * 脚本执行该程序时,提供以下的系统属性: * java.endorsed.dirs=$JAVA_ENDORSED_DIRS -classpath $CLASSPATH * java.security.manager * java.security.policy=$CATALINA_BASE/conf/catalina.policy * catalina.base=$CATALINA_BASE * catalina.home=$CATALINA_HOME * java.io.tmpdir=$CATALINA_TMPDIR * * param args Command line arguments to be processed */ public static void main(String args) / 设置debug for (int i = 0; i = 1) log(Loading startup class); Class startupClass = catalinaLoader.loadClass (org.apache.catalina.startup.Catalina); Object startupInstance = startupClass.newInstance(); / 设置startupInstance的父ClassLoader,相当于执行: / Catalina startupInstance = new Catailina(); / startupInstance.setParentClassLoader(sharedLoader); / 详情参考类org.apache.catalina.startup.Catalina if (debug = 1) log(Setting startup class properties); String methodName = setParentClassLoader; Class paramTypes = new Class1; paramTypes0 = Class.forName(java.lang.ClassLoader); Object paramValues = new Object1; paramValues0 = sharedLoader; Method method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); / 使用main方法获得的参数args来执行process方法,相当于: / startupIcess(args); / 详情参考类org.apache.catalina.startup.Catalina if (debug = 1) log(Calling startup class process() method); methodName = process; paramTypes = new Class1; paramTypes0 = args.getClass(); paramValues = new Object1; paramValues0 = args; method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); catch (Exception e) System.out.println(Exception during startup processing); e.printStackTrace(System.out); System.exit(2); /* * 返回$CATALINA_HOME变量。如果该变量没有定义,则将之赋值为用户的当前工作目录。 */ private static String getCatalinaHome() return System.getProperty(catalina.home, System.getProperty(user.dir); /* * 返回$CATALINA_BASE变量。如果该变量没有定义,则将之赋值为$CATALINA_HOME。 */ private static String getCatalinaBase() return System.getProperty(catalina.base, getCatalinaHome(); /* * 输出LOG信息。 */ private static void log(String message) System.out.print(Bootstrap: ); System.out.println(message); /* * 输出由异常引起的LOG信息。 */ private static void log(String message, Throwable exception) log(message); exception.printStackTrace(System.out); (b) class ClassLoaderFactorypackage org.apache.catalina.startup;import java.io.File;import java.io.IOException;import .URL;import java.util.ArrayList;import java.util.jar.JarEntry;import java.util.jar.JarFile;import org.apache.catalina.loader.StandardClassLoader;/* * Utility class for building class loaders for Catalina. The factory * method requires the following parameters in order to build a new class * loader (with suitable defaults in all cases): A set of directories containing unpacked classes (and resources) that should be included in the class loaders repositories. A set of directories containing classes and resources in JAR files. Each readable JAR file discovered in these directories will be added to the class loaders repositories. ClassLoader instance that should become the parent of the new class loader. * * author Craig R. McClanahan * version $Revision: 1.8 $ $Date: 2002/02/17 08:26:02 $ */public final class ClassLoaderFactory /* * Debugging detail level for processing the startup. */ private static int debug = 0; /* * Return the debugging detail level. */ public static int getDebug() return (debug); /* * 设置DEBUG级别 */ public static void setDebug(int newDebug) debug = newDebug; /* * 该类是一个静态类,用来创建和返回ClassLoader对象(实际上是StandardClassLoader对象) * 它将根据设置和参数返回apache定置的ClassLoader对象,以完成自己的类载入 * * param unpacked 类路径CLASSPATH的数组 * param packed 含有JAR文件的类路径 * param parent 父ClassLoader对象。当一个ClassLoader对象无法完成类载入时,它将请求父对象帮助 * * exception Exception if an error occurs constructing the class loader */ public static ClassLoader createClassLoader(File unpacked, File packed, ClassLoader parent) throws Exception if (debug = 1) log(Creating new class loader); / list里将被填入所有需要附加到CLASSPATH上去的文件名 ArrayList list = new ArrayList(); / Add unpacked directories if (unpacked != null) for (int i = 0; i = 1) log( Including directory + file.getAbsolutePath(); URL url = new URL(file, null, file.getCanonicalPath() + File.separator); list.add(url.toString(); / Add packed directory JAR files if (packed != null) for (int i = 0; i packed.length; i+) File directory = packedi; if (!directory.isDirectory() | !directory.exists() | !directory.canRead() continue; String filenames = directory.list(); for (int j = 0; j = 1) log( Including jar file + file.getAbsolutePath(); URL url = new URL(file, null, file.getCanonicalPath(); list.add(url.toString(); / 填好了list / 创建StandardClassLoader对象,并返回 String array = (String) list.toArray(new Stringlist.size(); StandardClassLoader classLoader = null; if (parent = null) classLoader = new StandardClassLoader(array); else classLoader = new StandardClassLoader(array, parent); classLoader.setDelegate(true); return (classLoader); /* * 输出日志 */ private static void log(String message) System.out.print(ClassLoaderFactory: ); System.out.println(message); /* * 输出日志和异常信息 */ private static void log(String message, Throwable exception) log(message); exception.printStackTrace(System.out); (c) class SecurityClassLoadpackage org.apache.catalina.startup;/* * Static class used to preload java classes when using the * Java SecurityManager so that the defineClassInPackage * RuntimePermission does not trigger an AccessControlException. * * author Glenn L. Nielsen * version $Revision: 1.1 $ $Date: 2001/12/30 01:58:20 $ */* * 该类只有一个静态方法,其作用仅仅相当于一个函数 * 该静态方法负责载入一些指定的类 * package org.apache.catalina.core * package org.apache.catalina.connector * package org.apache.catalina.loader * package org.apache.catalina.session * package org.apache.catalina.util * 这些包都在$CATALINA_HOME/server/catalina.jar文件中 * (由此看来,该静态方法的合法参数仅为catalinaLoader?) */public final class SecurityClassLoad static void securityClassLoad(ClassLoader loader) throws Exception if( System.getSecurityManager() = null ) return; String basePackage = org.apache.catalina.; loader.loadClass (basePackage + core.ApplicationContext$PrivilegedGetRequestDispatcher); loader.loadClass (basePackage + core

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论