古道长亭

Contact me with ixiaoqiang0011@gmail.com


  • 首页

  • 归档

  • 分类

  • 关于

  • Book

  • 搜索

Tomcat 类加载机制剖析

时间: 2022-12-28   |   分类: Tomcat   | 字数: 1739 字 | 阅读约: 4分钟 | 阅读次数:

Tomcat 类加载机制剖析

Java类(.java)—> 字节码⽂件(.class) —> 字节码⽂件需要被加载到jvm内存当中(这个过程就是⼀个类加载的过程)

类加载器(ClassLoader,说⽩了也是⼀个类,jvm启动的时候先把类加载器读取到内存当中去,其他的类(⽐如各种jar中的字节码⽂件,⾃⼰开发的代码编译之后的.class⽂件等等))

要说 Tomcat 的类加载机制,⾸先需要来看看 Jvm 的类加载机制,因为 Tomcat 类加载机制是在 Jvm 类加载机制基础之上进⾏了⼀些变动。

一、JVM类加载机制

JVM 的类加载机制中有⼀个⾮常重要的⻆⾊叫做类加载器(ClassLoader),类加载器有⾃⼰的体系,Jvm内置了⼏种类加载器,包括:

  • 引导类加载器
  • 扩展类加载器
  • 系统类加载器

他们之间形成⽗⼦关系,通过 Parent 属性来定义这种关系,最终可以形成树形结构。

类加载器作用
BootstrapClassLoader 引导类加载器c++编写,加载java核⼼库 java.*,⽐如rt.jar中的类,构造ExtClassLoader和AppClassLoader
ExtClassLoader 扩展类加载器java编写,加载扩展库 JAVA_HOME/lib/ext⽬录下的jar中的类,如classpath中的jre ,javax.*或者java.ext.dir指定位置中的类
SystemClassLoader/AppClassLoader 系统类加载器默认的类加载器,搜索环境变量 classpath 中指明的路径

另外:⽤户可以⾃定义类加载器(Java编写,⽤户⾃定义的类加载器,可加载指定路径的 class ⽂件)

当 JVM 运⾏过程中,⽤户⾃定义了类加载器去加载某些类时,会按照下⾯的步骤(⽗类委托机制)

  1. ⽤户⾃⼰的类加载器,把加载请求传给⽗加载器,⽗加载器再传给其⽗加载器,⼀直到加载器树的顶层

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

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

因此,按照这个过程可以想到,如果同样在 classpath 指定的⽬录中和⾃⼰⼯作⽬录中存放相同的class,会优先加载 classpath ⽬录中的⽂件

二、双亲委派机制

  • 定义

    当某个类加载器需要加载某个.class⽂件时,它⾸先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,⾃⼰才会去加载这个类。

  • 作用

    • 防⽌重复加载同⼀个.class。通过委托去向上⾯问⼀问,加载过了,就不⽤再加载⼀遍。保证数据安全。

    • 保证核⼼.class不能被篡改。通过委托⽅式,不会去篡改核⼼.class,即使篡改也不会去加载,即使加载也不会是同⼀个.class对象了。不同的加载器加载同⼀个.class也不是同⼀个.class对象。这样保证了class执⾏安全(如果⼦类加载器先加载,那么我们可以写⼀些与java.lang包中基础类同名的类, 然后再定义⼀个⼦类加载器,这样整个应⽤使⽤的基础类就都变成我们⾃⼰定义的类了。)Object类 —–> ⾃定义类加载器(会出现问题的,那么真正的Object类就可能被篡改了)

三、Tomcat的类加载机制

Tomcat 的类加载机制相对于 Jvm 的类加载机制做了⼀些改变。没有严格的遵从双亲委派机制,也可以说打破了双亲委派机制

⽐如:有⼀个tomcat,webapps下部署了两个应⽤

  • app1/lib/a-1.0.jar com.lagou.edu.Abc

  • app2/lib/a-2.0.jar com.lagou.edu.Abc

不同版本中Abc类的内容是不同的,代码是不⼀样的

  • 引导类加载器 和 扩展类加载器 的作⽤不变

  • 系统类加载器正常情况下加载的是 CLASSPATH 下的类,但是 Tomcat 的启动脚本并未使⽤该变量,⽽是加载tomcat启动的类,⽐如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下

  • Common 通⽤类加载器加载Tomcat使⽤以及应⽤通⽤的⼀些类,位于CATALINA_HOME/lib下,⽐如servlet-api.jar

  • Catalina ClassLoader ⽤于加载服务器内部可⻅类,这些类应⽤程序不能访问

  • Shared ClassLoader ⽤于加载应⽤程序共享类,这些类服务器不会依赖

  • Webapp ClassLoader,每个应⽤程序都会有⼀个独⼀⽆⼆的Webapp ClassLoader,他⽤来加载本应⽤程序 /WEB-INF/classes 和 /WEB-INF/lib 下的类。

tomcat 8.5 默认改变了严格的双亲委派机制

⾸先从 Bootstrap Classloader加载指定的类

如果未加载到,则从 /WEB-INF/classes加载

如果未加载到,则从 /WEB-INF/lib/*.jar 加载

如果未加载到,则依次从 System、Common、Shared 加载(在这最后⼀步,遵从双亲委派

机制)

#Tomcat#
QQ扫一扫交流

标题:Tomcat 类加载机制剖析

作者:古道长亭

声明: 欢迎加群交流!

如有帮助,欢迎多多交流 ^_^

微信打赏

支付宝打赏

读写分离实战
读写分离剖析
  • 文章目录
  • 站点概览
古道长亭

古道长亭

Always remember that your present situation is not your final destination. The best is yet to come.

226 日志
57 分类
104 标签
GitHub Gitee
友情链接
  • 古道长亭的BOOK
  • JAVA学习
标签云
  • Mysql
  • 搜索引擎
  • Mybatis
  • 容器
  • 架构
  • 消息队列
  • Flink
  • Sharding sphere
  • 流处理
  • 缓存
  • 一、JVM类加载机制
  • 二、双亲委派机制
  • 三、Tomcat的类加载机制
© 2019 - 2024 京ICP备19012088号-1
0%