手把手带你写一个 MiniTomcat
郭屹
前 Sun Microsystems Java 研发工程师
1792 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 22 讲
开篇词 (1讲)
手把手带你写一个 MiniTomcat
15
15
1.0x
00:00/00:00
登录|注册

15|类加载机制的改变:如何自定义ClassLoader?

你好,我是郭屹。今天我们继续手写 MiniTomcat。
上节课我们引入了多应用的支持,实现了通过路由将请求发送到不同应用中,在这个过程中我们也定义了 WebappClassLoader 这个自定义的类加载器来进行隔离。
但是光有隔离还不够,因为不同的类加载器有不同的加载方式和顺序,而 Java 自身的系统级 ClassLoader 也不能完全满足我们的需要,所以这节课我们要继续扩展这个话题,深入讨论自定义的 ClassLoader。

类加载器原理

我们平时写程序的时候似乎感觉不到类加载器,其实是因为 Java 在帮我们默认使用,我们的程序中每涉及到一个类的使用,运行时 Java 都会通过一个类加载器来加载它。Java 里面对它的定义是:类加载器是一个对象,它负责加载别的类(Class Loader is an object that is responsible for loading classes)。
我们简单回顾一下一个 Java 对象是如何在 JVM 里面运行起来的。一个简单的语句 new Test(); 大体会经过下面几个步骤。
步骤一:类级别的工作。具体某个类的加载过程只会做一次。
加载:找到 class 文件,打开并获取它的字节流,按照虚拟机规范存储在 JVM 里,同时创建一个和它匹配的 java.lang.Class 类对象。这个时候,类的定义和内存表达就准备好了,但是还没有开始对象的创建。
链接:这个阶段执行类的链接过程,给类分配内存。具体它有三个动作要做。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了如何在MiniTomcat框架中引入自定义加载器,重点讲解了定义Loader通用接口和调整Container通用接口的过程。作者首先介绍了MiniTomcat框架中的两类ClassLoader,并着重介绍了自定义的WebappClassLoader。随后,详细讲解了定义Loader通用接口的具体步骤,并展示了对Container通用接口的调整。文章还提到了需要对ContainerBase中的getLoader和setLoader方法进行调整,以及涉及到其他类的修改。通过本文,读者可以了解到如何在MiniTomcat框架中引入自定义加载器,并对相关接口和类进行调整,以满足特定需求。文章还对Tomcat的类加载过程进行了详细说明,包括CommonClassLoader和WebappClassLoader的代码定义和加载类的过程。这篇文章对于想要深入了解类加载机制和自定义ClassLoader的读者来说是一份有价值的技术指南。文章还介绍了如何调整服务器代码以及对MiniTomcat进行测试,最后总结了本节课的内容并提出了思考题,引发读者思考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一个 MiniTomcat》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • Geek_50a5cc
    双亲委托 是 将类的加载放到上一层处理,如果加载到,就不需要重复加载;所以遇到一个User类,不管是版本1,2,都会加载,不会再去处理其他的User类

    作者回复: 是的是的

    2024-01-22归属地:北京
    1
  • peter
    请教老师几个问题: Q1:CommonLoader与CommonClassLoader是什么关系? CommonClassLoader并没有继承CommonLoader。 Q2:Tomcat只有Common加载器吗? MiniTomcat用Common加载器来加载服务器通用的类,用WebappClassLoader来加载应用的类。但是,文章中讲到的Tomcat的类加载图中,只有Common,并没有WebappClassLoader。 Q3:System是扩展类加载器吗? 文中几个关于类加载的图中,都有“System”这个措辞,它是指扩展类加载器吗? Q4:类的版本怎么体现? 一个类有多个版本,怎么体现?通过类名字来体现? Q5:类被加载以后是放在方法区吗? 比如,类Person,被加载以后会创建一个针对Person的对象,假设名字是A。那么,加载以后得类Person和A是被放在内存中的方法区吗?

    作者回复: Q1,loader是Tomcat自己的包装,classloader是Java的。MiniTomcat同样这么做的。 Q2,common用于Tomcat的lib目录下的包,webappclassloader用于webapps目录下的应用 Q3,system是指Java提供的加载器,包括app, ext和根 Q4,一个类,修改一下,重新编译,就是一个新的版本了 Q5,类本身的信息放在方法区的(现在叫Meta区)。这些也依赖于JVM本身的实现。

    2024-01-11归属地:北京
    1
  • HH🐷🐠
    JVM 里一个类的唯一标识是 ClassLoader + 类名, 按照双亲委派模式都是由相同的 ClassLoader 去加载, 无疑会冲突。 老师, 还有一个问题, CommonClassLoader 是不是要指定一下 delegate,默认为 false

    作者回复: 可以指定delegate,没问题。不过我没注意查Tomcat这一部分源代码是怎么处理的。

    2024-01-14归属地:广东
  • InfoQ_1f089af08bc8
    老师能否讲解一下类加载器的findClass(String name)和loadClass(String name)之间有什么关联吗?

    作者回复: load是规定一个步骤策略,比如说第一步用system去找,第二步用ext加载器去找,规定了一个步骤。 find是根据位置按照字节码规范去加载这个类,然后用defineClass就把字节流变成了一个类。

    2024-01-10归属地:北京
  • InfoQ_1f089af08bc8
    请问老师,URLStreamHandler 这个类的作用是干什么的?

    作者回复: 一个资源的定位用url表示,如何打开这个资源呢?通过某种协议,如http, https,或者file,这个handler就是来处理协议的。

    2024-01-10归属地:北京
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部