1 基本信息摘要:分别介绍Tomcat和Webshpher类加载机制。 作者:戴小丹 林晓咏 2 Tomcat类加载机制Tomcat Server在启动的时候将构造一个ClassLoader树,以保证模块的类库是私有的 - Bootstrap - 载入JVM自带的类和/jre/lib/ext/*.jar 每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类,系统默认的 contextClassLoader是systemClassLoader,所以一般而言java程序在执行时可以使用JVM自带的类、$ JAVA_HOME/jre/lib/ext/中的类和/中的类,可以使用Thread.currentThread(). setContextClassLoader(...);更改当前线程的contextClassLoader,来改变其载入类的行为ClassLoader被组织成树形,一般的工作原理是: 3 Websphere类加载机制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的情况下,应用程序的类加载器将不存在,同一个应用服务器上的所有应用程序将共用同一个类加载器,这也就意味着不同的应用程序之间的类是共享的,应用程序间不能存在同名的类。 4 Jboss启动及加载过程详细参考: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服务的生命周期. |
tomcat和websphere类加载机制
最新推荐文章于 2023-09-28 03:58:21 发布