1.1. 第二篇:Tomcat架构源码解析
1.1.1. Tomcat源码准备工作
Tomcat启动时序图。
![776488aad8d9f33d36fdf294e2cadd16.png](https://i-blog.csdnimg.cn/blog_migrate/14df849a2eb6dad134ab0818bf4c5dc7.jpeg)
生命周期Lifecycle接口。
由于所有的组件均存在初始化、启动、停止等生命周期方法.拥有生命周期管理的特性,所以Tomcat在设计的时候, 基于生命周期管埋抽象成了一个接口Lifecycle ,而组件Server、 Service. Container、 Executor、 Connector 组件,都实现了一个生命周期的接口,从而具有了以下生命周期中的核心方法:
1) init() :初始化组件
2) start() :启动组件
3) stop() :停止组件
4) destroy() : 销毁组件
![a8f0be235f75fae675d0d395d393ec6d.png](https://i-blog.csdnimg.cn/blog_migrate/484ff02d5ace6cce75e658fa43f139d0.jpeg)
Tomcat各个组件的默认实现
上面我们提到的sexver、Service、 Engine、 Host、 Context都是接口,下图中罗列了这些接口的默认实现类。 当前对于Endpoint组件来说,在Tomcat中没有对应的Endpoint接口,但是有一个抽象类AbstractEndpoint , 其下有三个实现类: NioEndpoint、Nio2Endpoint、AprEndpoint。
![e8346002a27e8e0eca15173b5287e47b.png](https://i-blog.csdnimg.cn/blog_migrate/24b9b285347789c5f4a084227ae0d1cf.jpeg)
ProtocolHandler接口及其实现
![f09ea9a42b3f110debfa4dd37ee94d4a.png](https://i-blog.csdnimg.cn/blog_migrate/29e615a439540604f61bec01e1e5d4da.jpeg)
1.2.2 Tomcat初始化源码解析
通过启动脚本的方式找入口,打开startup.bat文件,可以看到
![5b7fdc80859667e36e48aa83ea234e65.png](https://i-blog.csdnimg.cn/blog_migrate/3290b94e55bc9abac135b2d83485b69f.jpeg)
根据代码内容打开 Catalina.bat 文件
![3fa25e949b10ea649c1772f9038381ca.png](https://i-blog.csdnimg.cn/blog_migrate/2597dc7406c84e6bb3a388a66be7662c.jpeg)
找到启动类 org.apache.catalina.startup.Bootstrap
执行该类的main方法。
![b06db3134cc362a6a49ea40ed417acfc.png](https://i-blog.csdnimg.cn/blog_migrate/8b6c520736d3f5c0167872112da62ce3.jpeg)
然后调用init方法,初始化Catalina对象。
![0ceed77868b844f1fd67f46a75ac09e9.png](https://i-blog.csdnimg.cn/blog_migrate/7d4b3e382fd87f612f40003a1fac3ecd.jpeg)
执行load方法
![1695d512cf02e51d7bcfd04c3b1e92ec.png](https://i-blog.csdnimg.cn/blog_migrate/21649c490ded6d2369ab9a0fa018904a.jpeg)
底层通过反射的方式去执行Catalina的load方法。
![832c0d54c0e5c2ee63cc916470b507ae.png](https://i-blog.csdnimg.cn/blog_migrate/fd8e025374099362953d3ad9fbc33d0b.jpeg)
执行Catalina类的load方法,解析server.xml配置文件,构建Server Service等对象,构建完成后,准备执行初始化的方法。
![b0176a9d1f68d451c11bf289f566ff35.png](https://i-blog.csdnimg.cn/blog_migrate/8d19345f9582bb921180e25af921fffc.jpeg)
解析server.xml配置文件,构建StandardServer等对象。
![617456f9840474170fd1afe0424e036c.png](https://i-blog.csdnimg.cn/blog_migrate/c8f3101f5db377d0161dc42adf6c3e75.jpeg)
构建对象
![07689f922e5f9688d36e387fedb741ba.png](https://i-blog.csdnimg.cn/blog_migrate/709decad354e797eeb9e31c081a7a767.jpeg)
构建对象源码
![3b63049456f4efa5db981b0763de99fc.png](https://i-blog.csdnimg.cn/blog_migrate/2c91525baa8301c0cb1fa994b0c5b242.jpeg)
1.1.3. Server初始化服务器解析
服务初始化源代码
此处使用的是模板方法设计模式
![589205c0f0251a47276cb0231eec3871.png](https://i-blog.csdnimg.cn/blog_migrate/f0f8442fcd73034f7de7bf83384fca6d.jpeg)
Server的;类图。
![1f9852905a2a94a0f1a2497e520b1eae.png](https://i-blog.csdnimg.cn/blog_migrate/c56f1a0b080e57e0c5710815d71253d0.jpeg)
Server是Tomcat最顶层的容器,代表着整个服务器
Tomcat中其标准实现:org.apache.catalina.core.StandardServer类
StandardServer继承结构类图如上图:除了实现Server接口还需要继承Lifecycle
好处:生命周期统一接口Lifecycle把所有的启动、停止、关闭等都放在一起统一管理
1.1.4. Service初始化服务解析
启动执行service初始化操作。
![7a70d137d08d7e34feb9f9704ff10195.png](https://i-blog.csdnimg.cn/blog_migrate/5837c58869e9b307f3d2c5d0af5105c8.jpeg)
Service的类图
![32a7eb37ff915925d55e9afce79c1514.png](https://i-blog.csdnimg.cn/blog_migrate/58ceddcc2d16b15abba6e50ebf75b7c1.jpeg)
Service:一个Tomcat包含多个Service
Tomcat中其标准实现:org.apache.catalina.core.StandardServic类
StandardService继承结构类图如上图:除了实现Service接口还需要继承Lifecycle
好处:生命周期统一接口Lifecycle把所有的启动、停止、关闭等都放在一起统一管理
1.1.5. Executor线程池与Connector连接器解析初始化
配置的线程池及其使用线程池。
![818a3e0cd9862c19e75d65a4c987d65e.png](https://i-blog.csdnimg.cn/blog_migrate/234cfcef537013cf703ff185f7623743.jpeg)
使用线程池
![34da8798be02263b74cabcfd83e60d45.png](https://i-blog.csdnimg.cn/blog_migrate/6d0ffcf23bf68d11422dd1f6b15669b5.jpeg)
使用JDK自带的jconsole工具查看线程信息。
![e8041cff5dbd8ba68c88973a87a6cece.png](https://i-blog.csdnimg.cn/blog_migrate/f54afccae709edfe5a31a27ddeb2b9b5.jpeg)
Connector连接器的作用是监听8080端口,使用request和response处理请求。网络通信:
Connector(连接器),监听网络端口、接受网络连接请求、读取请求网络字节流。
根据具体应用层协议(HTTP/AJP)解析字节流,生成统一的Tomcat Request对象
将Tomcat Request对象转成标准的ServletRequest,调用Servlet容器,得到ServletResponse,将ServletResponse转成 Tomcat Response对象。将Tomcat Response对象转成网络字节流,将响应字节流写会服务器。
ProtocolHandler由包含了三个部件:Endpoint、Processor、 Adapter
Endpoint用来处理底层Socket的网络连接。
Processor用于将Endpoint接收到的Socket封装成Request。
Adapter充当适配器,用于将Request转换为ServletRequest交给Container进行具体的处理。
选择IO模型。
![d9d6da04a297d5133c087ca2ec3038c9.png](https://i-blog.csdnimg.cn/blog_migrate/86c1f75fb0bfa56dbd1559957ffefc15.jpeg)
协议处理器初始化。
![6673c3e808181b261f98e48428152527.png](https://i-blog.csdnimg.cn/blog_migrate/b0420fe696582e0404b14a6276514461.jpeg)
端点初始化
![b7265d2e2c7a6f44a61c8eaaf18a79ef.png](https://i-blog.csdnimg.cn/blog_migrate/e0b9624ec3b6c0cb24b42233983ecedc.jpeg)
绑定IO模型
![148a85c69df9b4116c9cfeb6f2c82f56.png](https://i-blog.csdnimg.cn/blog_migrate/8adec4b742f59c4cd38ed346eb4755d5.jpeg)
绑定NIO模型
![f41741dae8f47f0d0ebda0128b25a678.png](https://i-blog.csdnimg.cn/blog_migrate/31886dbbf40bb3615bfd6107d07c9eb5.jpeg)
1.1.6. Tomcat启动源码解析
当所有的组件全部初始化完成后,下面需要让所有的组件启动。
![e7f0bc320e58604844499edcb5113c0a.png](https://i-blog.csdnimg.cn/blog_migrate/bbe0804377c3dea734c7f7245e7f4b84.jpeg)
执行Catalina对象的start方法
![33ca3d9ba1fc0493a0bc7d477f66783f.png](https://i-blog.csdnimg.cn/blog_migrate/864afecbb4156cd15c44af942127291e.jpeg)
Catalina启动
![0337067ee8b44788420dfe1a0dc3dad1.png](https://i-blog.csdnimg.cn/blog_migrate/b99688b366b6be440cfd9593de31c096.jpeg)
StandardServer启动。
![e613f1e24d587b858743fb56c4a1fb8a.png](https://i-blog.csdnimg.cn/blog_migrate/c6b4c34b596cc77b722a25c46ef75355.jpeg)
StandardService的启动方法。
![3455ad5f179e5c1e781ba4f078f08be7.png](https://i-blog.csdnimg.cn/blog_migrate/4b94607f551159e699ec5d9b95e0ce38.jpeg)
Connector连接器启动。
![0c53d2207d50c1808547eede55dc60cb.png](https://i-blog.csdnimg.cn/blog_migrate/5a6da5d7f57da3018d52a6dd40ab8346.jpeg)
协议处理器启动。
![ea2b9cf193fb67d1f18eb5418322ee4a.png](https://i-blog.csdnimg.cn/blog_migrate/c8345ab5eac7ba6b64ce25031c1a5a53.jpeg)
端点启动。
![5495152a7d5f9bef5cc9451af045948c.png](https://i-blog.csdnimg.cn/blog_migrate/1d2bebc2c1f3946c5f57c3491002ff09.jpeg)
具体的IO模型启动。
![718b47c1279f9ceaec9dd6f31008a42a.png](https://i-blog.csdnimg.cn/blog_migrate/cc29e10ea37a650c180bcab6efc1433e.jpeg)
NioEndpoint的启动方法中,创建线程去接收和处理请求。
![bed4c543a4ef81e88808c7d33ac1b40f.png](https://i-blog.csdnimg.cn/blog_migrate/95bcc5f3c3369ece86b665c0f3776ab2.jpeg)
启动Acceptor和Poller线程来接收和处理客户端发送过来的请求。
![2f73529f0836706bf64d8db681a5cf97.png](https://i-blog.csdnimg.cn/blog_migrate/1fd4a06fc6ac95ea7f64f7f9a517a341.jpeg)
使用Acceptor用来接收客户端请求。
![4f0b9e7c68c3ba082eab038c7ac2c181.png](https://i-blog.csdnimg.cn/blog_migrate/3d20ec92c49d9f3fb4739fb244d0b6ac.jpeg)
使用Poller线程来处理读写操作。
![d71abc801aeae23e04ed59bc18dc85f3.png](https://i-blog.csdnimg.cn/blog_migrate/d3b62bfed9bb787cd54a311be58a5e98.jpeg)
StandardEngine启动代码。
![eb1ccc9bb0a72c3f598ea5780cd232a8.png](https://i-blog.csdnimg.cn/blog_migrate/8e3b57922d63439fb4bdd554620a7e47.jpeg)
启动子容器
![e3d53b7a6de13f373e8225e4a485fa2d.png](https://i-blog.csdnimg.cn/blog_migrate/16abc8d6b6d8af6e86cfb2561e8c8c85.jpeg)
启动子容器的方法。
![72f8631c5400ed8e126f10164defd4c3.png](https://i-blog.csdnimg.cn/blog_migrate/fec49c081d3ae0b9aadccdef64f458ca.jpeg)
通过JDK本地线程池,启动线程的方式启动子容器。执行AbstractExecutorService 类的submit方法。
![acd35ee22005146b0f7ee9b5dfae7f31.png](https://i-blog.csdnimg.cn/blog_migrate/096014e0ae99c9deab36611b09577a45.jpeg)
执行JDK的线程代码。
![a6a1b3836bfb20ac136eac39ac88af64.png](https://i-blog.csdnimg.cn/blog_migrate/ecb15f7309049c71078520211cd9814c.jpeg)
StandardHost启动。
![ef8c8dd05fb5e4c82bee615197546ed2.png](https://i-blog.csdnimg.cn/blog_migrate/b466ae8db4d79769316030bf99956c46.jpeg)
StandardContext启动。
![d5d4e58cbc3d0f187ad5e2037b29047e.png](https://i-blog.csdnimg.cn/blog_migrate/f5cfb87dc944d20c64c65054ff07cd95.jpeg)
看到这里,对tomcat有没有一个更深入的了解了呢?如果没有,没关系!小编这里有个0元深入了解tomcat的机会,继续往下看。。。
0元学编程!Tomcat源码架构与性能优化!3天到课率即返学费!直播课更是穿插抽奖环节,报名就送10G的java架构师课程视频!!!此次课程适合哪些人:1. 想深入学习tomcat架构的小伙伴2. 想精通tomcat源代码的小伙伴3. 想掌握百万并发tomcat性能优化的小伙伴 7月15日 下周三直播开讲 点击下方了解更多,直接报名,不明白的小伙伴也可以私信我哦!
0元课程大纲:
![64d49ec861caffbddd23db5e860726cd.png](https://i-blog.csdnimg.cn/blog_migrate/55b101833f3f44391db57e3e6a531425.jpeg)