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等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
Tomcat中的类是怎么被一步步加载的?的更多相关文章
- 解决Nginx+Tomcat中https转http请求问题---解决js加载使用http的问题
解决js加载使用http的问题 控制台错误提示: Mixed Content: The page at '' was loaded over HTTPS, but requested an insec ...
- jQuery中的ready方法及实现按需加载css,js
模拟jQuery中的ready方法及实现按需加载css,js 一.ready函数的实现 经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的 ...
- Cesium中Clock控件及时间序列瓦片动态加载
前言 前面已经写了两篇博客介绍Cesium,一篇整体上简单介绍了Cesium如何上手,还有一篇介绍了如何将Cesium与分布式地理信息处理框架Geotrellis相结合.Cesium的强大之处也在于其 ...
- 模拟jQuery中的ready方法及实现按需加载css,js实例代码
这篇文章介绍了模拟jQuery中的ready方法及实现按需加载css,js实例代码,有需要的朋友可以参考一下 一.ready函数的实现经常用jQuery类库或其他类库中的ready方法,有时候 ...
- web工程启动时,在一个类中延迟加载Bean,因为该Bean类可能还没被JVM加载
问题描述: (1)javaWeb项目启动中,还没启动完成,在下面这个类加载另一个Bean类, (2)通过getBean方法获取到该Bean,可以获取到,不为null (3)但是,调用该Bean的方法 ...
- Spring中通过变量和import标签来控制加载哪些bean
需求:根据设置变量,来加载某个spring的bean的配置文件,这个配置文件中,有某些使用的bean.在一些情况下,不希望这些bean被初始化和加载进context中,也不需要被外面访问到. 在spr ...
- netcore2.0 ORM框架中如何配置自定义的主外键加载
环境:netcore2.0 DB :mysql ORM:Ant https://github.com/yuzd/AntData.ORM/tree/netcore2 [给我一个star吧] NUGET: ...
- WPF 中的 Pack URI地(资源文件加载)
参考资源网http://msdn.microsoft.com/zh-cn/library/aa970069.aspx#Absolute_vs_Relative_Pack_URIs 在 Windows ...
- Q开头的类找不到,无法加载插件:com.mysema.maven:apt-maven-plugin
http://www.jspxcms.com/documentation/297.html 如果出现无法加载com.mysema.maven:apt-maven-plugin插件的情况,通常是由于ma ...
随机推荐
- PTA数据结构与算法题目集(中文) 7-6
PTA数据结构与算法题目集(中文) 7-6 7-6 列出连通集 (25 分) 给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时, ...
- mysql物理结构
MySQL是通过文件系统对数据和索引进行存储的. MySQL从物理结构上可以分为日志文件和数据索引文件. MySQL在Linux中的数据索引文件和日志文件都在/var/lib/mysql目录下. 日志 ...
- 【php】面向对象(三)
知识点关键词:FSCICATS一. f => final: a) 是一个修饰符,用来修饰类和成员方法 b) 使用final修饰符修饰的类不能被继承,使用final修饰符修饰的成员方法,不能被重写 ...
- kali2016&2019的安装使用
先解释一下,为什么要说2016&2019哪,这是因为有一些测试靶机环境在2016以上的系统安装不通过,所以有时候会特意找2016的镜像来用. 一.下载镜像 1.下载镜像当然要到官方去下载了: ...
- windows的注册表有什么用?
注册表是什么 注册表是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息.早在Windows 3.0推出OLE技术的时候,注册表就已经出现.随后推出的Window ...
- Linux(Fedora)系统下配制8086汇编环境
1.到www,nasm.us下载nasm 2.解压并安装nasm #tar -xzvf nasm-2.11.08.tar.gz #cd nasm-2.11.08 #./configure #make ...
- python调用js
安装 pip install PyExecJS 方法 eval() 输入参数:source(JS语句).cwd(路径) 返回值:result(语句执行结果) compile() 输入参数:source ...
- 发布公开的pod
发布公开的pod 方便项目 通过cocoapods 使用,便于版本版本管理,下面是简单步奏: 0.首次操作先要注册Trunk: pod trunk register zhujin001xb@163.c ...
- 最近遇到adb connection 问题,总结一下
最近eclipse总是遇到adb connection问题,网上搜索了一些解决方法,在cmd tool工具下adb kill-server ,adb start-server ,甚至重启都无效.然后我 ...
- windows/linux下如何更换Python的pip源
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:xlixiaohui PS:如有需要Python学习资料的小伙伴可以 ...