zoukankan      html  css  js  c++  java
  • Tomcat类加载机制和JAVA类加载机制的比较

    图解Tomcat类加载机制

     

      说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷。

      之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试。后来同事指导,说是直接把java类复制到src下就可以了。很纳闷....为什么会优先加载src下的java文件(编译出的class),而不是jar包中的class呢?

      现在了解tomcat的类加载机制,原来一切是这么的简单。

    类加载

      在JVM中并不是一次性把所有的文件都加载到,而是一步一步的,按照需要来加载。

      比如JVM启动时,会通过不同的类加载器加载不同的类。当用户在自己的代码中,需要某些额外的类时,再通过加载机制加载到JVM中,并且存放一段时间,便于频繁使用。

      因此使用哪种类加载器、在什么位置加载类都是JVM中重要的知识。

    JVM类加载

      JVM类加载采用 父类委托机制,如下图所示:

      JVM中包括集中类加载器:

      1 BootStrapClassLoader 引导类加载器

      2 ExtClassLoader 扩展类加载器

      3 AppClassLoader 应用类加载器

      4 CustomClassLoader 用户自定义类加载器

      他们的区别上面也都有说明。需要注意的是,不同的类加载器加载的类是不同的,因此如果用户加载器1加载的某个类,其他用户并不能够使用。

      当JVM运行过程中,用户需要加载某些类时,会按照下面的步骤(父类委托机制):

      1 用户自己的类加载器,把加载请求传给父加载器,父加载器再传给其父加载器,一直到加载器树的顶层。

      2 最顶层的类加载器首先针对其特定的位置加载,如果加载不到就转交给子类。

      3 如果一直到底层的类加载都没有加载到,那么就会抛出异常ClassNotFoundException。

      因此,按照这个过程可以想到,如果同样在CLASSPATH指定的目录中和自己工作目录中存放相同的class,会优先加载CLASSPATH目录中的文件。

    Tomcat类加载

      在tomcat中类的加载稍有不同,如下图:

      当tomcat启动时,会创建几种类加载器:

      1 Bootstrap 引导类加载器 

      加载JVM启动所需的类,以及标准扩展类(位于jre/lib/ext下)

      2 System 系统类加载器 

      加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下。

      3 Common 通用类加载器 

      加载tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下,比如servlet-api.jar

      4 webapp 应用类加载器

      每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于 WEB-INF/lib下的jar文件中的class 和 WEB-INF/classes下的class文件。

      当应用需要到某个类时,则会按照下面的顺序进行类加载:

      1 使用bootstrap引导类加载器加载

      2 使用system系统类加载器加载

      3 使用应用类加载器在WEB-INF/classes中加载

      4 使用应用类加载器在WEB-INF/lib中加载

      5 使用common类加载器在CATALINA_HOME/lib中加载

    问题扩展

      通过对上面tomcat类加载机制的理解,就不难明白 为什么java文件放在Eclipse中的src文件夹下会优先jar包中的class?

      这是因为Eclipse中的src文件夹中的文件java以及webContent中的JSP都会在tomcat启动时,被编译成class文件放在 WEB-INF/class 中。

      而Eclipse外部引用的jar包,则相当于放在 WEB-INF/lib 中。

      因此肯定是 java文件或者JSP文件编译出的class优先加载。

      通过这样,我们就可以简单的把java文件放置在src文件夹中,通过对该java文件的修改以及调试,便于学习拥有源码java文件、却没有打包成xxx-source的jar包。

      另外呢,开发者也会因为粗心而犯下面的错误。

      在 CATALINA_HOME/lib 以及 WEB-INF/lib 中放置了 不同版本的jar包,此时就会导致某些情况下报加载不到类的错误。

      还有如果多个应用使用同一jar包文件,当放置了多份,就可能导致 多个应用间 出现类加载不到的错误。

  • 相关阅读:
    【Uvalive4960】 Sensor network (苗条树,进化版)
    【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
    【UVA 1395】 Slim Span (苗条树)
    【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
    【UVA 10369】 Arctic Network (最小生成树)
    【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
    【UVA 11183】 Teen Girl Squad (定根MDST)
    【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
    【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
    【LA 5713 】 Qin Shi Huang's National Road System (MST)
  • 原文地址:https://www.cnblogs.com/blackmanbali/p/9026401.html
Copyright © 2011-2022 走看看