zoukankan      html  css  js  c++  java
  • Tomcat中的类是怎么被一步步加载的?

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

    一、类加载

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

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

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

    二、JVM类加载

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

    JVM中包括集中类加载器:

    BootStrapClassLoader 引导类加载器

    ExtClassLoader 扩展类加载器

    AppClassLoader 应用类加载器

    CustomClassLoader 用户自定义类加载器

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

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

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

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

    如果一直到底层的类加载都没有加载到,那么就会抛出异常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

    欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563 群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

    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包文件,当放置了多份,就可能导致 多个应用间 出现类加载不到的错误。

    为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!

    欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563

    群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

  • 相关阅读:
    《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第八章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
    我的superui开源后台bootstrap开发框架
    LayoutInflater 总结
    Android屏幕分辨率概念(dp、dip、dpi、sp、px)
    android studio安装问题
  • 原文地址:https://www.cnblogs.com/twodog/p/12135928.html
Copyright © 2011-2022 走看看