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

16|大功告成:完成MiniTomcat

你好,我是郭屹。今天我们继续手写 MiniTomcat。
上节课我们引入了自定义的类加载器,先尝试了用系统提供的 ClassLoader 加载某个类,如果是 delegate 模式,那么父级类加载器去加载这个类,之后再试着由原本的类加载器加载类;如果不是 delegate 模式,使用父级类加载器加载,如果父级类加载器为空,就用系统级类加载器加载。
随后我们还进一步区分了 Context、Host,对 MiniTomcat 进行了两层容器包装,实现解耦。
而这节课我们计划做进一步的优化调整,一是在进入 Host 层之前,预先装载 Context,二是对 Servlet 访问路径支持自定义。最后通过配置文件来配置服务器,跟 Tomcat 一样。
现在我们一起来动手实现。

项目结构

这节课我们把所有的 ClassLoader 移到 /loader 目录里,随后使用 server.xml 和 web.xml 分别管理 Host 启动配置与 Servlet 加载配置,这也是我们这节课的重点,你可以看一下现在的目录结构。
MiniTomcat
├─ conf
│ ├─ server.xml
├─ src
│ ├─ main
│ │ ├─ java
│ │ │ ├─ com
│ │ │ │ ├─ minit
│ │ │ │ │ ├─ connector
│ │ │ │ │ │ ├─ http
│ │ │ │ │ │ │ ├─ DefaultHeaders.java
│ │ │ │ │ │ │ ├─ HttpConnector.java
│ │ │ │ │ │ │ ├─ HttpHeader.java
│ │ │ │ │ │ │ ├─ HttpProcessor.java
│ │ │ │ │ │ │ ├─ HttpRequestImpl.java
│ │ │ │ │ │ │ ├─ HttpRequestLine.java
│ │ │ │ │ │ │ ├─ HttpResponseImpl.java
│ │ │ │ │ │ │ ├─ ServletProcessor.java
│ │ │ │ │ │ │ ├─ SocketInputStream.java
│ │ │ │ │ │ │ ├─ StatisResourceProcessor.java
│ │ │ │ │ │ ├─ HttpRequestFacade.java
│ │ │ │ │ │ ├─ HttpResponseFacade.java
│ │ │ │ │ ├─ core
│ │ │ │ │ │ ├─ ApplicationFilterChain.java
│ │ │ │ │ │ ├─ ApplicationFilterConfig.java
│ │ │ │ │ │ ├─ ContainerBase.java
│ │ │ │ │ │ ├─ ContainerListenerDef.java
│ │ │ │ │ │ ├─ FilterDef.java
│ │ │ │ │ │ ├─ FilterMap.java
│ │ │ │ │ │ ├─ StandardContext.java
│ │ │ │ │ │ ├─ StandardContextValve.java
│ │ │ │ │ │ ├─ StandardHost.java
│ │ │ │ │ │ ├─ StandardHostValve.java
│ │ │ │ │ │ ├─ StandardPipeline.java
│ │ │ │ │ │ ├─ StandardWrapper.java
│ │ │ │ │ │ ├─ StandardWrapperValve.java
│ │ │ │ │ ├─ loader
│ │ │ │ │ │ ├─ CommonClassLoader.java
│ │ │ │ │ │ ├─ CommonLoader.java
│ │ │ │ │ │ ├─ WebappClassLoader.java
│ │ │ │ │ │ ├─ WebappLoader.java
│ │ │ │ │ ├─ logger
│ │ │ │ │ │ ├─ Constants.java
│ │ │ │ │ │ ├─ FileLogger.java
│ │ │ │ │ │ ├─ LoggerBase.java
│ │ │ │ │ │ ├─ SystemErrLogger.java
│ │ │ │ │ │ ├─ SystemOutLogger.java
│ │ │ │ │ ├─ session
│ │ │ │ │ │ ├─ StandardSession.java
│ │ │ │ │ │ ├─ StandardSessionFacade.java
│ │ │ │ │ ├─ startup
│ │ │ │ │ │ ├─ BootStrap.java
│ │ │ │ │ ├─ util
│ │ │ │ │ │ ├─ CookieTools.java
│ │ │ │ │ │ ├─ StringManager.java
│ │ │ │ │ │ ├─ URLDecoder.java
│ │ │ │ │ ├─ valves
│ │ │ │ │ │ ├─ AccessLogValve.java
│ │ │ │ │ │ ├─ ValveBase.java
│ │ │ │ ├─ Connector.java
│ │ │ │ ├─ Container.java
│ │ │ │ ├─ ContainerEvent.java
│ │ │ │ ├─ ContainerListener.java
│ │ │ │ ├─ Context.java
│ │ │ │ ├─ InstanceEvent.java
│ │ │ │ ├─ InstanceListener.java
│ │ │ │ ├─ Loader.java
│ │ │ │ ├─ Logger.java
│ │ │ │ ├─ Pipeline.java
│ │ │ │ ├─ Request.java
│ │ │ │ ├─ Response.java
│ │ │ │ ├─ Session.java
│ │ │ │ ├─ SessionEvent.java
│ │ │ │ ├─ SessionListener.java
│ │ │ │ ├─ Valve.java
│ │ │ │ ├─ ValveContext.java
│ │ │ │ ├─ Wrapper.java
│ │ ├─ resources
│ ├─ test
│ │ ├─ java
│ │ │ ├─ test
│ │ │ │ ├─ HelloServlet.java
│ │ │ │ ├─ TestFilter.java
│ │ │ │ ├─ TestListener.java
│ │ │ │ ├─ TestServlet.java
│ │ ├─ resources
├─ webapps
│ ├─ app1
│ │ ├─ WEB-INF
│ │ │ ├─ classes
│ │ │ │ ├─ test
│ │ │ │ │ ├─ HelloServlet.class
│ │ │ │ │ ├─ TestFilter.class
│ │ │ │ │ ├─ TestListener.class
│ │ │ │ │ ├─ TestServlet.class
│ │ │ ├─ web.xml
│ │ ├─ hello.txt
│ ├─ app2
│ │ ├─ WEB-INF
│ │ │ ├─ classes
│ │ │ │ ├─ test
│ │ │ │ │ ├─ HelloServlet.class
│ │ │ │ │ ├─ TestFilter.class
│ │ │ │ │ ├─ TestListener.class
│ │ │ │ │ ├─ TestServlet.class
│ │ │ ├─ web.xml
│ │ ├─ hello.txt
├─ pom.xml
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何手写MiniTomcat,并对项目结构进行了详细说明。作者在文章中提到了引入自定义的类加载器、对MiniTomcat进行了两层容器包装、优化调整等内容。在项目结构方面,作者将所有的ClassLoader移到/loader目录里,并使用server.xml和web.xml分别管理Host启动配置与Servlet加载配置。文章还介绍了如何预装载Context,遍历/webapps目录后会启动所有的Context,实现了在Host调用前预装载Context。此外,文章还涉及了对server.xml的解析和BootStrap类的调整。整体而言,本文适合想要了解MiniTomcat实现细节的读者阅读。文章还引入了web.xml文件,通过自定义配置建立访问路径与类名之间的联系。通过解析web.xml文件,实现了简化URL的路径请求。最后,文章还介绍了MiniTomcat的完整性和友好性,使其成为一个完整的小型Tomcat。

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

全部留言(2)

  • 最新
  • 精选
  • HH🐷🐠
    目前能想到的是 Servlet 注解或者直接增加 mapping 配置

    作者回复: 还有几个大的,只支持http, 不能与web server独立运行,没有embedded

    2024-01-14归属地:广东
  • peter
    请教老师几个问题: Q1:server.xml中为什么配置两个端口? <?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> </Engine> </Service> </Server> 一个8005,另外一个8080,有什么区别?到底有哪一个? Q2:Tomcat为什么用Digester? 既然Digester比较复杂,使用的人也比较少,为什么Tomcat还用它? Q3:Tomcat内部怎么表示多个Host? 一个主机有一套处理实例吗?类似于“类”,一样的代码,但一个具体的主机就是一个实例,比如有3个主机,就有3个实例。是这样吗?

    作者回复: Q1,8005是一个监听端口,专门用于SHUTDOWN来关闭Tomcat的,MiniTomcat没有实现它 Q2,不是Tomcat还用它,而是Tomcat一开始就用它,从来没有变过。复杂但是灵活扩展,因为复杂性高一些,后面没什么人跟着学。大师们的东西经常复杂,大部分程序员学不会,因此没什么人用,另一个例子就是Spring的webflux。 Q3,host是虚拟主机,server.xml文件中可以配置的,url中server:port这一段就表示的不同的虚拟主机,不同的虚拟主机内部就是不同的Host对象。

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