每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类
系统默认的contextClassLoader是systemClassLoader,所以一般而言 java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类 可以使用Thread.currentThread().setContextClassLoader(...);更改当前线程的contextClassLoader,来改变其载入类的行为 ClassLoader被组织成树形,一般的工作原理是: 1) 线程需要用到某个类,于是contextClassLoader被请求来载入该类 2) contextClassLoader请求它的父ClassLoader来完成该载入请求 3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入 注意:WebApp?ClassLoader的工作原理和上述有少许不同: 它先试图自己载入类(在ContextBase?/WEB-INF/...中载入类),如果无法载入,再请求父ClassLoader完成 由此可得: - 对于WEB APP线程,它的contextClassLoader是WebApp?ClassLoader - 对于Tomcat Server线程,它的contextClassLoader是CatalinaClassLoader 3 类的查找 ClassLoader类中loadClass方法为缺省实现,用下面的顺序查找类: 1、调用findLoadedClass方法来检查是否已经被加载。如果没有则继续下面的步骤。 2、如果当前类装载器有一个指定的委托父装载器,则用委托父装载器的loadClass方法加载类,也就是委托给父装载器加载相应的类。 3、如果这个类装载器的委托层级体系没有一个类装载器加载该类,则使用类装载器定位类的特定实现机制,调用findClass方法来查找类。 4 - 部分原代码分析 4.1 - org/apache/catalina/startup/Bootstrap. java Bootstrap中定义了三个classloader:commonLoader,catalinaLoader,sharedLoader.三者关系如下: //注意三个自己定置的ClassLoader的层次关系: // systemClassLoader (root) // +--- commonLoader // +--- catalinaLoader // +--- sharedLoader Tomcat Server线程的起点 构造ClassLoader树,通过Thread.currentThread().setContextClassLoader(catalinaLoader)设置当前的classloader为catalinaLoader。 载入若干类,然后转入org.apache.catalina.startup.Catalina类中 4.2 org.apache.catalina.loader.StandardClassLoader. java 通过看loadClass这个方法来看tomcat是如何加载类的,顺序如下: (0) Check our previously loaded class cache查找已经装载的class clazz = findLoadedClass(name); (1) If a system class, use system class loader通过系统classloader来装载class ClassLoader loader = system; clazz = loader.loadClass(name); (2) Delegate to our parent if requested如果有代理则使用父类classloader ClassLoader loader = parent; if (loader == null) loader = system; clazz = loader.loadClass(name); (3) Search local repositories 查找本地类池,比如$CATALINA_HOME/server clazz = findClass(name); (4) Delegate to parent unconditionally 默认使用代理装载器 [查看代码] 4.3 - org/apache/catalina/startup/ClassLoaderFactory. java 根据设置创建并返回StandardClassLoader的实例 [查看代码] 4.4 - org/apache/catalina/loader/StandardClassLoader. java 类载入器 4.5 - org/apache/catalina/startup/SecurityClassLoad. java 该类仅包含一个静态方法,用来为catalinaLoader载入一些类 *在一个JVM中可能存在多个ClassLoader,每个ClassLoader拥有自己的NameSpace。一个ClassLoader只能拥有一个class对象类型的实例,但是不同的ClassLoader可能拥有相同的class对象实例,这时可能产生致命的问题。如ClassLoaderA,装载了类A的类型实例A1,而ClassLoaderB,也装载了类A的对象实例A2。逻辑上讲A1=A2,但是由于A1和A2来自于不同的ClassLoader,它们实际上是完全不同的,如果A中定义了一个静态变量c,则c在不同的ClassLoader中的值是不同的。 |
tomcat classload 原理
最新推荐文章于 2024-04-05 00:04:19 发布