`
idealab
  • 浏览: 195341 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Tomcat类加载器体系结构

    博客分类:
  • Java
阅读更多
   与Java语言相似,Tomcat提供了分级类加载机制,当然,最顶端非BootStrap Loader莫属,它由C++编写,JVM启动且完成初始化后首先被调用。不过在Tomcat中类加载体系中,缺少了ExtClassLoader的身影(待验证),ExtClassLoader加载sun公司提供的扩展机制(参考文章:<<Extension Mechanism Architecture>>)。下面是架构图:


上图展示了各层类加载器以及类文件搜索路径,Tomcat为每个部署到其中的Web项目定义一个类加载器(如上图中WebappAClassLoader、WebappBClassLoader),其类文件搜索路径即为%CATALINA_HOME%\webapps\项目名称\WEB-INF\lib\;
%CATALINA_HOME%\webapps\项目名称\WEB-INF\classes\。Tomcat自己定义了一个BootStrap类,在org.apache.catalina.startup.BootStrap定义,其作用是:
1、定义公共类加载器
    private Object catalinaDaemon = null;//定义catalina服务器守护程序实例

    protected ClassLoader commonLoader = null;
    protected ClassLoader catalinaLoader = null;
    protected ClassLoader sharedLoader = null;

    private void initClassLoaders() {
        try {
            ClassLoaderFactory.setDebug(debug);
            commonLoader = createClassLoader("common", null);
            catalinaLoader = createClassLoader("server", commonLoader);
            sharedLoader = createClassLoader("shared", commonLoader);
        } catch (Throwable t) {
            log("Class loader creation threw exception", t);
            System.exit(1);
        }
    }

我们看到commonLoader的父类加载器为null,即在委派机制下它将把类加载任务直接委派给JVM所使用的BootStrap Loader,但为什么是null呢?因为JVM所使用的BootStrap Loader是用C++编写的。
catalinaDaemon为服务器从启动至停止都存在的守护线程。createClassLoader函数利用ClassLoaderFactory类在工厂模式下创建,创建代码如下:
 public static ClassLoader createClassLoader(File unpacked[],File packed[], URL urls[], ClassLoader parent)throws Exception {
...
        //获得将要创建的类加载器的类文件搜索路径
        String array[] = (String[]) list.toArray(new String[list.size()]);
        StandardClassLoader classLoader = null;
        if (parent == null)//父加载器为JVM使用的BootStrap Loader
            classLoader = new StandardClassLoader(array);
        else
            classLoader = new StandardClassLoader(array, parent);
        classLoader.setDelegate(true);//设置该类加载器遵循委派模式
        return (classLoader);
}

Tomcat提供两种类加载器供使用,一种是如上代码中所述的标准类加载器StandardClassLoader,用以实例化为commonLoader、catalinaLoader和sharedLoader,在org.apache.catalina.loader.StandardClassLoader定义,它不提供热部署功能;另外一种是专为Web程序所提供的WebClassLoader,它用以实例化为各部署项目的类加载器,在org.apache.catalina.loader.WebappClassLoader定义,提供热部署功能,也就是在发生ClassLoader搜索路径下的资源改变的动作之后,服务器自动重新加载之。
2、初始化catalina守护程序:
    public void init()
        throws Exception
    {
        // Set Catalina path
        setCatalinaHome();
        setCatalinaBase();
        
        initClassLoaders();
        Thread.currentThread().setContextClassLoader(catalinaLoader);
        SecurityClassLoad.securityClassLoad(catalinaLoader);

        /*利用类加载器catalinaClassLoader加载Catalina,并调用后者的process方法,该方法设置%CATALINA_HOME%,%CATALINA_BASE%,并根据参数配置启动catalina*/
        Class startupClass =
            catalinaLoader.loadClass
            ("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.newInstance();
        
        /*将SharedClassLoader设为Catalina类的ClassLoader*/
        String methodName = "setParentClassLoader";
        Class paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
            
        method.invoke(startupInstance, paramValues);
        catalinaDaemon = startupInstance;
    }

本段代码实现了利用CatalinaClassLoader加载Catalina类,并创建其实例。但很有意思的是,创建实例之后Catalina的类加载器却被设置为SharedClassLoader。
我们知道Catalina是Tomcat容器的代言人,也就是一个在容器生命周期内都存在的类,我们所设计的Servlet是被放置在这个容器里面供调用的,从代码层来讲也就是被实例化,然后引用。同时,在Java类加载器体系结构中定义到:被引用类默认由依赖类的ClassLoader加载,而这样设计的原因是,运行时相同层次的ClassLoader所加载的类无法看到其他ClassLoader所加载的类,可这又是为什么呢?这是Java语言的安全特性所要求的(进一步探讨,请参阅《深入Java虚拟机》)。由上所述,可以知道如果要引用Servlet的话,得有Catalina的ClassLoader出马去加载,但是我们之前已经看到了,每一个Web项目都有一个特定的WebappClassLoder加载,并且Catalina需要引用的可是同时部署到其中的许多个Web项目的Servlet,这就出现了矛盾。但是,我们仔细看看WebappClassLoader的设计,它的父加载器可是SharedClassLoader哦(SharedClassLoader加载的是部署到容器中的多个Web项目共用的资源),故聪明的小花猫把Catalina的类加载器设置为了SharedClassLoader,这样利用父加载器加载Catalina,而子加载器来加载Servlet,岂不是一个绝妙的设计!
注意:代码中利用到了强大的反射机制。

延伸探究:
http://blog.chinaunix.net/u2/83532/showart_1418390.html
http://blog.163.com/haizai219@126/blog/static/44412555200810111429791/
  • 大小: 20.1 KB
7
0
分享到:
评论

相关推荐

    Tomcat体系结构与插件配置教程图解

    二、tomcat服务器体系结构  1.Server整个Servlet容器组合,可以包含一个或多个  2.service:它由一个或者多个Connector组成,以及一个Engine,负责处理所有Connector所获得的客户请求。  3.Connector:客户端与...

    tomcat6、7、8、9, maven3.5

    Apache Tomcat 3.3是Apache Tomcat 3.x体系结构的最新延续; 它比3.2.4更先进,这是“老”的生产质量释放。 版本3.2.4是“旧的”生产质量版本,现在仅在维护模式。 版本3.1.1是旧版本。 所有的Apache Tomcat 3.X版本...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 189 7.4.1 类与类加载器 / 189 7.4.2 双亲委派模型 / 191 7.4.3 破坏双亲委派模型 / 194 7.5 本章小结 / 197 第8章 虚拟机字节码执行引擎 / 198 8.1 概述 / 198 8.2 运行时栈帧结构 / 199 8.2.1 局部变量...

    Java虚拟机

    9.2.1 Tomcat:正统的类加载器架构 9.2.2 OSGi:灵活的类加载器架构 9.2.3 字节码生成技术与动态代理的实现 9.2.4 Retrotranslator:跨越JDK版本 9.3 实战:自己动手实现远程执行功能 9.3.1 目标 9.3.2 思路 ...

    java初学者必看

    1.7.3 Java虚拟机的体系结构 1.8 垃圾收集器 1.9 本章习题 第2章 Java开发环境 2.1 J2SE的下载和安装 2.1.1 J2SE的下载 2.1.2 J2SE的安装 2.2 环境变量的配置与测试 2.2.1 设置环境变量path 2.2.2 设置环境...

    健身房管理信息系统设计.doc

    1.2.3 J2EE应用系统体系结构 J2EE体系结构采用典型的多层次结构,分别为客户端、表现层、业务逻辑层、数据层 ,各层次间相对独立和松散耦合,保证了使用开发框架的应用良好的结构。如J2EE体系 结构图1-2所示: 图1-...

    J2EE应用开发详解

    17 2.1 构建开发环境 17 2.1.1 安装JDK 17 2.1.2 安装Tomcat 21 2.1.3 安装Eclipse 23 2.2 配置开发环境 23 2.3 小结 26 第3章 Java的反射机制 27 3.1 Java反射API 27 3.2 加载类的实例 29 3.2.1 加载class对象的两...

    Java数据编程指南

    数据定义 基本数据操作 数据完整性 表达式 连接 合并 子...Tomcat安装和配置 JRun 3.0安装和配置 安装检索 附录E 在WebLogic 6.0上配置并部署EJB 设置配置属性 生成EJB容器类 加载...

    Spring.3.x企业应用开发实战(完整版).part2

    1.4 Spring体系结构 1.5 Spring 3.0的新功能 1.5.1 核心API更新到Java 5. 1.5.2 Spring表达式语言 1.5.3 可通过Java类提供IoC配置信息 1.5.4 通用类型转换系统和属性格式化系统 1.5.5 数据访问层新增OXM功能 1.5.6 ...

    Spring3.x企业应用开发实战(完整版) part1

    1.4 Spring体系结构 1.5 Spring 3.0的新功能 1.5.1 核心API更新到Java 5. 1.5.2 Spring表达式语言 1.5.3 可通过Java类提供IoC配置信息 1.5.4 通用类型转换系统和属性格式化系统 1.5.5 数据访问层新增OXM功能 1.5.6 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 6.1.1 servlet接口 196 6.1.2...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 6.1.1 servlet接口 196 6.1.2...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 6.1.1 servlet接口 196 6.1.2...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 6.1.1 servlet接口 196 6.1.2...

    Java开发技术大全 电子版

    14.5.2Swing组件的体系结构468 14.5.3使用Swing组件编写GUI的层次结构468 14.6顶层容器469 14.6.1框架类(JFrame)使用示例469 14.6.2小应用程序(JApplet)使用示例472 14.6.3对话框(JDialog)使用示例473 ...

    Hibernate3的帮助文档

    3. 体系结构(Architecture) 3.1. 概况(Overview) 3.2. 实例状态 3.3. JMX整合 3.4. 对JCA的支持 4. 配置 4.1. 可编程的配置方式 4.2. 获得SessionFactory 4.3. JDBC连接 4.4. 可选的配置属性 4.4.1. SQL...

    java面试题

    72.6. Struts体系结构中的组件 69 72.7. struts如何实现国际化 70 72.8. struts2.0的常用标签 71 72.9. action是单实例还是多实例,为什么? 73 72.10. Struts的validate框架是如何验证的? 74 72.11. ...

    外文翻译 stus MVC

    1:外文原文 Struts——an open-source MVC implementation This article introduces Struts, a Model-View-Controller implementation that uses servlets and JavaServer Pages (JSP) technology....

    hibernate 框架详解

    3. 体系结构(Architecture) 3.1. 概况(Overview) 3.2. 实例状态 3.3. JMX整合 3.4. 对JCA的支持 4. 配置 4.1. 可编程的配置方式 4.2. 获得SessionFactory 4.3. JDBC连接 4.4. 可选的配置属性 4.4.1. ...

    hibernate3.04中文文档.chm

    3. 体系结构(Architecture) 3.1. 概况(Overview) 3.2. 实例状态 3.3. JMX整合 3.4. 对JCA的支持 4. 配置 4.1. 可编程的配置方式 4.2. 获得SessionFactory 4.3. JDBC连接 4.4. 可选的配置属性 4.4.1. ...

Global site tag (gtag.js) - Google Analytics