标签:style blog http io ar os 使用 java sp
Tomcat Server 在启动的时候将构造一个 ClassLoader 树,以保证模块的类库是私有的
Tomcat Server 的 ClassLoader 结构图如下:
- Bootstrap - 载入 JVM 自带的类和 /jre/lib/ext/*.jar
- System - 载入 /*.class
- Common - 载入 /common/... ,它们对 TOMCAT 和所有的 WEB APP 都可见
- Catalina - 载入 /server/... ,它们仅对 TOMCAT 可见,对所有的 WEB APP 都不可见
- Shared - 载入 /shared/... ,它们仅对所有 WEB APP 可见,对 TOMCAT 不可见(也不必见)
- WebApp - 载入 ContextBase?/WEB-INF/... ,它们仅对该 WEB APP 可见
每个运行中的线程都有一个成员 contextClassLoader ,用来在运行时动态地载入其它类,系统默认的contextClassLoader 是systemClassLoader ,所以一般而言java 程序在执行时可以使用JVM 自 带的类、 $ JAVA_HOME/jre/lib/ext/ 中的类和 / 中的类,可以使用 Thread.currentThread(). setContextClassLoader(...); 更改当前线程的 contextClassLoader ,来改变其载入类的行为 ClassLoader 被组织成树形,一般的工作原理是:
1) 线程需要用到某个类,于是 contextClassLoader 被请求来载入该类
2) contextClassLoader 请求它的父 ClassLoader 来完成该载入请求
3) 如果父 ClassLoader 无法载入类,则 contextClassLoader 试图自己来载入
Java 应用程序运行时,在class 执行和被访问之前,它必须通过类加载器加载使之有效,类加载器是JVM 代码的一部分,负责在JVM 虚拟机中查找和加载所有的Java 类和本地的lib 库。类加载器的不同配置影响到应用程序部署到应用程序服务器上运行时的行为。JVM 和WebSphere 应用程序服务器提供了多种不同的类加载器配置, 形成一个具有父子关系的分层结构。
WebSphere 中类加载器的层次结构图1 所示:
如上图所示,WebSphere 中类加载器被组织成一个自上而下的层次结构,最上层是系统的运行环境JVM ,最下层是具体的应用程序,上下层之间形成父子关系。
关于WebSphere 的类加载器的层次结构,以下的几点说明可能更有助于进一步的理解类的查找和加载过程:
如果一个类加载器以及它所有的父类加载器都无法找到所需的类,系统就会抛出 ClassNotFoundExecption 异常或者NoClassDefFoundError 的错误。
类加载器的委托模式
类加载器有一个重要的属性:委托模式(Delegation Mode ,有时也称为加载方式:Classloader mode )。委托模式决定了类加载器在查找一个类的时候,是先查找类加载器自身指定的类路径还是先查找父类加载器上的类路径。
类加载器的委托模式有两个取值:
有了委托模式的概念,我们可以更加灵活的配置在类加载器的层次结构中类的加载和查找方式。表1 中给出了在WebSphere 的类加载器层次结构中各个类加载器的委托模式的定义,并给出了不同的类加载器内类的生命周期。
注意:在上表中,"JVM Class loader" 因为在类加载器的最顶层,它没有父类加载器,因此其委托模式为N/A,"WebSphere Extensions Class loader" 和"WebSphere lib/app Class loader" 的委托模式固定为表中的取值,不可配置,其它的类加载器的委托模式都是可以配置的。
WebSphere 中的类加载器策略
WebSphere 中对类加载器有一些相关的配置,称为类加载器策略(class loader policy )。类加载器策略指类加载器的独立策略(class loader isolation policy ), 通过类加载器策略设置,我们可以为WAS 和应用程序的类加载器进行独立定义。
每个WAS 可以配置自己的应用程序类加载器策略,WAS 中的每个应用程序也可以配置自己的Web 模块类加载器策略,下面我们对这两种策略分别介绍。
1 .应用服务器(WAS )配置:应用程序类加载器策略
应用服务器对应用程序类加载器策略有两种配置:
2 .应用程序配置:Web 模块类加载器策略
应用程序中对Web 模块类加载器有两种配置:
从上面的定义可以看出,不同的类加载器策略的配置下,类加载器的层次结构上的某些类加载器可能不存在。比如在应用程序服务器的应用程序类加载器策略定义为 single 的情况下,应用程序的类加载器将不存在,同一个应用服务器上的所有应用程序将共用同一个类加载器,这也就意味着不同的应用程序之间的类是共享的,应用程序间不能存在同名的类。
详细参考: http://tech.it168.com/j/2007-06-27/200706271521984.shtml
1) org.jboss.Main.main(String[]) 为入口 .
2) main 函数创建一个名叫” jboss ”的线程组 , 然后创建一个属于该组的线程 , 在线程中执行 boot 方法 .
3) boot 方法首先处理 main 函数中的参数 ( 及一些其它的系统环境设置 ), 接着就用系统的属性创建了org.jboss.system.server.ServerLoader 实例 [new ServerLoader(props)].
4) ServerLoader 注册 Jboss 相关的类路径 , 包括 XML 解析器 , jboss-jmx.jar, concurrent.jar 及其它的一些额外的类路径 .
5) ServerLoader 通过 load(ClassLoader) 方法创建 Jboss Server 实例 . 参数 ClassLoader 是 ClassLoader parentCL = Thread.currentThread(). getContextClassLoader( ) 得到的当前线程的类加载器 . 创建的Server 实例是 org.jboss.system.server.Server 接口的实现 . load(ClassLoader) 方法的细节:
Ø 用 jar 包及在 ServerLoader 中注册的类路径创建一个 URLClassLoader 的实例 , 把传入的 ClassLoader作为该 URLClassLoader 的 parent.
Ø Server 接口的实现类由系统属性 jboss.server.type 决定 , 默认是 org.jboss.system.server.ServerImpl.
Ø URLClassLoader 通过无参构造函数加载 Server 接口实现的实例 . 在加载前把当前线程的类加载器置为该URLClassLoader, 在加载完成后再置回之前传入的 ClassLoader.
6) Server 实例用系统属性进行初始化 [server.init(props)].
7) 服务起动 [server.start()]. 起动过程的默认实现如下 :
Ø 把当前线程类型加载器置为加载该 Server 接口实现实例的 ClassLoader.
Ø 在 jboss 域内 , 通过 MBeanServerFactory 的 createMBeanServer(String) 方法创建 MbeanServer 实例 .
Ø 在 MBean Server 上注册 ServerImpl 和 ServerConfigImpl 两个 MBean.
Ø 初始化统一的类加载仓库 (unified class loader repository), 用来装载服务器配置目录及其它可选目录下的jar 文件 . 对于每一个 jar 文件和类目录都会创建一个相应的 org.jboss.jmx.loading.UnifiedClassLoader实例 , 并且注册到统一的仓库中 . 其中一个 UnifiedClassLoader 实例会被设置为当前线程上下文的ClassLoader. [?: This effectively makes allUnifiedClassLoaders available through the thread context class loader.]
Ø 接下来创建 org.jboss.system.ServiceController 的 MBean 实例 . ServiceController 管理 JBoss MBean服务的生命周期 .
标签:style blog http io ar os 使用 java sp
原文地址:http://www.cnblogs.com/svennee/p/4075514.html