2020-11-16

一、官网下载Tomcat 的源码导入IDEA
1、地址:http://tomcat.apache.org/ 左侧 Download Tomcat 9,在网页最下面下载Tomcat源码;
在这里插入图片描述
下载完了直接解压得到apache-tomcat-9.0.39文件夹。

2、打开IDEA导入解压后的文件夹 , 选择File->Open->选择tomcat的源码目录(我下载的是apache-tomcat-9.0.39);
注意:打开的目录是刚刚解压的文件夹,而不是打开解压文件夹的中的那个子目录(我是这么操作的)。

3、① 在项目配置中设置JDK和源码目录:File->Project Structure->project->project SDK
②设置 java包设置为Tomcat项目的Sources文件:File->Project Structure->Modules
在这里插入图片描述

二、Tomcat启动重要文件
startup源码分析
我觉得要研究一个技术的源码要从它是怎么启动运行的开始,特别是很复杂的源码,所有我就从Tomcat的启动开始。
在这里插入图片描述

在Tomcat的bin目录下有两个启动Tomcat的文件,一个是startup.bat,它用于windows环境下启动Tomcat;另一个是startup.sh,它用于Linux环境下Tomcat的启动。大概看了下这两个文件中的实现思路差不多一样的,我就看了startup.bat(windows启动文件)

以下是startup.bat文件,我加了一些注解:
在这里插入图片描述
在这里插入图片描述
通过以上阅读可以得到一个结论: startup.bat文件实际上就做了一件事情 -> 启动catalina.bat
这样我也明白了,为什么在此之前我在windows下配置了catalina.bat就可以使用catalina run 启动Tomcat了。所以未必一定要通过startup.bat来启动Tomcat,用catalina.bat start也是可以的。

catalina.bat源码分析
既然在 startup.bat有关联到 catalina.bat ,那么就肯定要看看这个文件是干嘛的了。

由于注解比代码多,我就梳理一下大概的执行逻辑

首先会直接跳到mainEntry代码段 -> 在确定CATALINA_HOME下有catalina.bat后再把CATALINA_HOME赋给变量CATALINA_BASE -> 之后再去获得CLASSPATH(就是我们配置的环境变量)-> 系统拿到classpath路径后把它和CATALINA_HOME拼接在一起,最终定位到一个叫bootstrap.jar的文件;
在这里插入图片描述
然后到 doStart代码块(当然还有doDebug和doRun)并设定参数,最终跳转到execCmd代码段;

通过以上阅读可以得到一个结论: catalina.bat最终执行了Bootstrap类中的main方法。
读完catalina.bat会发现,我们可以通过设定不同的参数让Tomcat以不同的方式运行。比如说:在IDEA中可以选择debug等模式启动Tomcat的,也可以为其配置参数,在catalina.bat中我们可以看到了启动Tomcat背后的运作流程。

//public final class Bootstrap Bootstrap类的main方法
public static void main(String args[]) {

    synchronized (daemonLock) {
        if (daemon == null) {
            // Don't set daemon until init() has completed
            Bootstrap bootstrap = new Bootstrap();
            try {
                bootstrap.init();  //注意这个init()方法
            } catch (Throwable t) {
                handleThrowable(t);
                t.printStackTrace();
                return;
            }
            daemon = bootstrap;
        } else {
            // When running as a service the call to stop will be on a new
            // thread so make sure the correct class loader is used to
            // prevent a range of class not found exceptions.
            Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
刚刚说了,既然启动是靠Bootstrap的main()方法,那么不妨这么设置一下来运行项目:
运行tomcat源码我知道有两种方式,一种是使用 Ant 工具进行编译源码,一种是使用 Maven 工具,我使用的是 Maven,使用 Ant 得去下载 Ant 工具进行编译源码,一种是使用 Maven 工具,我使用的是 Maven,使用 Ant 得有IDEA Ant 的插件。我就说一下常用 Maven的操作:

首先:新建 catalina-home文件夹和像下图一样新建第一个pom.xml文件,并在apache-tomcat-9.0.39-src文件里新建第二个pom.xml(这两个pom文件可以在IDEA新建,也可以去其他项目中引入)
在这里插入图片描述
将apache-tomcat-9.0.39-src中的 conf文件复制到新建的catalina-home目录之下,再将以下内容复制到apache-tomcat-9.0.39-src中的pom.xml中,为什么需要这些依赖?就是运行tomcat需要这些依赖作为支撑。

<?xml version="1.0" encoding="UTF-8"?>

<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.tomcat</groupId>
<artifactId>Tomcat9.0</artifactId>
<name>Tomcat9</name>
<version>9.0.39</version>

<build>
    <finalName>Tomcat9</finalName>
    <sourceDirectory>java</sourceDirectory>
    <resources>
        <resource>
            <directory>java</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <encoding>UTF-8</encoding>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant</artifactId>
        <version>1.10.9</version>
    </dependency>
    <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant-apache-log4j</artifactId>
        <version>1.9.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant-commons-logging</artifactId>
        <version>1.9.5</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.rpc</groupId>
        <artifactId>javax.xml.rpc-api</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>wsdl4j</groupId>
        <artifactId>wsdl4j</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jdt.core.compiler</groupId>
        <artifactId>ecj</artifactId>
        <version>4.6.1</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.easymock</groupId>
        <artifactId>easymock</artifactId>
        <version>4.0.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 再将以下内容复制到外层pom.xml中: <?xml version="1.0" encoding="UTF-8"?>

<modelVersion>4.0.0</modelVersion>
<groupId>com.yang</groupId>
<artifactId>apache-tomcat-study</artifactId>
<name>Tomcat 9.0 Study</name>
<version>1.0</version>
<packaging>pom</packaging>

 <!--表示外层项目包含内层项目,这里要是tomcat版本不同的话,得修改一下,其实就是目录名-->
 <!--这种方式,类似构建微服务子模块与root项目的关系-->
<modules>
    <module>apache-tomcat-9.0.39-src</module>
</modules>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 在这里插入图片描述 然后:配置 Edit Configrations 在这里插入图片描述 Main class:

org.apache.catalina.startup.Bootstrap
1
vm options配置:

-Dcatalina.home=“E:\Code\apache-tomcat-9.0.39-src\catalina-home”
-Dfile.encoding=UTF8
-Duser.language=en
-Duser.region=US
1
2
3
4
在这里插入图片描述
在这里插入图片描述
保存运行即可即可。
在这里插入图片描述

三、Tomcat启动流程分析
启动的分析思路就先看到这里,先来看看service.xml到底配置了什么,于是就延伸出来了以下知识。我先说一下Tomcat 部署项目的方式,然后再来引入Tomcat的四大Servlet容器。

1、部署项目的方式
背景:我把Tomcat源码这个项目跑在了IDEA中

有三种方式:这三种方式并不是凭空产生,是有源码对应的。
在这里插入图片描述
(1)方式一:将web项目(应用)打包成 war 包,之后直接把这个war包放在webapps文件里
这种方式很好理解,就是把应用交给Tomcat去执行。
那么问题是Tomcat是怎么知道这个war包在webapps下,并它就是一个应用呢?
这个问题一会看到四大容器之一的Host就知道了。
在这里插入图片描述
在这里插入图片描述

(2)方式二:文件夹部署(只要有.class字节码即可运行项目)
第一种部署方式运行项目时,就是解压 war 包并且放到当前webapps目录下,此时是可以删除掉 war包的,只存在这个解压过来的文件也是可以独立运行项目的,这就引出了第二种部署方式,文件夹部署。

(3)方式二:配置应用指定的位置
把应用的位置指定在Host配置中。
在这里插入图片描述

2、Tomcat中Container管理四大Servlet容器
先来看看有哪一些,分别是
在这里插入图片描述

(1)Engine 表示整个Catalina Servlet引擎,是Container 组件的最高层,用来管理Host 或者Context的实现,是指定默认的Host为 localhost,名字指定为 Catalina,这就是为什么我们不指定Host也可以使用localhost虚拟主机来访问到应用。
在这里插入图片描述
也就是说一个 Engine 对应一个

List hosts;
1
(2)Host:我理解它是一个Engine管理下的一个虚拟主机,默认的虚拟主机是 localhost,也就是使用这个虚拟的主机来告诉我们要访问的 Tomcat 服务的位置,比如说使用 localhost://8080这个就是对应一个虚拟主机,然后再这个Host 里面来配置相应的应用,这样就是顺利访问到我们指定要访问的应用了。

当然可以存在多个虚拟主机,虽然它们的都是对应同一个 Tomcat,但是对应的应用不一样。一个虚拟主机里面也可以对应不同的应用。说白了,多个Host就是来做一个多个应用的指定位置的。
在这里插入图片描述
这也解释了为什么 Tomcat 会去webapps里找应用。
也就是说一个 Host 对应一个

List contexts;
1
(3)Context:直接理解的话,是上下文,但是我理解它是一个应用,或者是一个应用的配置,使用文件描述符配置文件的话,就会使用到 Context 容器。一个Context可以对应一个应用。
也就是说一个 Context 对应一个

List servlets;
1
(4)Wrapper:我理解它就是来对我们同一个 Servlet 的不同实例来进行分类管理的,也就是多次请求Tomcat 中同一个 Servlet 资源就会产生不同的 Servlet 实例,然而这些实例不可能任意在容器中,这样就不要管理,会造成混乱,所以就用 Weapper 来对同一类Servlet 的不同实例进行分类。Wrapper 还用来管理一个 Servlet 的生命周期。
也就是一个 Wrapper 对应一个 Servlet 类型。

List servlets;
1
而一个Context 就对应了一个Wrapper了

List wrappers;
1
Http请求在Container中的传递流程
在这里插入图片描述

好了,以上就是对 Container 接口的四大子接口的分析,它们分别对应四大 Servlet容器。

花了一个晚上搞清楚了这些接口和容器的关系了,直接看这个时序图:
在这里插入图片描述

3、分析启动时序图
从Bootstrap类的main方法开始,Tomcat会以链的方式逐级调用各个模块的init()方法进行初始化。待各个模块都初始化后,又会逐级调用各个模块的start()方法启动各个模块。
在这里插入图片描述
Bootstrap类首先会创建一个本类对象,然后调用init()方法进行初始化。

这里说一下,实例化是在堆空间中开辟相应的空间并赋默认值,初始化是调用 init() 方法赋实际值的一个过程。
在这里插入图片描述
假如是正常执行 start 的方式的话,可以看到在设置等待后,调用了本类对象的load()方法。查看load()方法的源码:
在这里插入图片描述
可以看到方法的最后通过反射的方式调用了成员变量catalinaDaemon的load()方法。通过跟踪源码可以看到catalinaDaemon是Bootstrap类的一个私有成员变量。

public final class Bootstrap {
private static final Log log = LogFactory.getLog(Bootstrap.class);
/**
* Daemon object used by main.di
/
private static final Object daemonLock = new Object();
private static volatile Bootstrap daemon = null;
/
*
* Daemon reference.
*/
//在init()方法中使用反射机制创建catalina赋给catalinaDaemon
private Object catalinaDaemon = null;
1
2
3
4
5
6
7
8
9
10
11
12
它会在Bootstrap的init()方法中通过反射的方式完成初始化。下面我们回过头来看init()方法的源码

在这里插入图片描述
可以看到init()方法创建了一个Catalina对象, 并把该对象赋给了catalinaDaemon。

之后再执行 getServer 方法来创建 Server 容器。

public interface Service extends Lifecycle {
/**
* @return the Container that handles requests for all
* Connectors associated with this Service.
*/
public Container getContainer();
1
2
3
4
5
6
来到了 Service 里,你会看到第一句就定义一个获取 Container 的方法,也就是可以获取一个唯一的Container。 在这个 Service 里,你会发现有 Executor和Connctor。

此时也就是说可以走 Container 被继承的四个 Servlet 容器了。

到此也就可以画出简单的一个UML图。来清晰展示这些接口之间的大概关系。

在这里插入图片描述
实现与继承关系:
在这里插入图片描述

四、Request请求过来Tomcat在干嘛
1、Pipeline

点赞
4

评论
7

分享

收藏
14

打赏

举报
关注
一键三连

点赞Mark关注该博主, 随时了解TA的最新博文
Tomcat 学习笔记.pdf
09-04
本文件为尚硅谷Tomcat的课堂学习笔记实录,讲解的清晰到位,适合入门Tomcat,掌握如何使用Tomcat
Tomcat学习笔记
YaoChung的博客
215
Web开发概述WEB通信WEB采用B/S通信模式,通过超文本传送协议(HTTP, Hypertext transport protocol)进行通信。通过浏览器地址栏编写URL,向服务器发送一个请求,服务器端根据请求进行相应的处理,处理完成之后,会向浏览器作出一个响应,及将服务器端资源发送给浏览器。软件架构 C/S架构:Client/Server 客户端/服务器。要求客户端电脑安装一个客户端程序。…

优质评论可以帮助作者获得更高权重
qq_43021786
代码搬运2.0:感谢大佬分享,很详细。4小时前回复
点赞
1
qq_24571813
Co_Co_爸:大佬,看了你的文章,内心的仰慕之情油然而生,赶紧给大佬点个赞!4小时前回复
点赞
1
kimol_justdo
爱码士爱码士不正经的kimol君:快进我的收藏夹15小时前回复
点赞
1
qq_37924905
爱码士爱码士水巷石子:nice,赞一个!21小时前回复
点赞
1
hihell
爱码士爱码士梦想橡皮擦:太赞了!66666622小时前回复
点赞
1
qq_40542534
爱码士爱码士strive_day:感谢博主分享,学到不少东西!23小时前回复
点赞
1
weixin_43423864
爱码士爱码士一起码代码:大佬一出手,精品果然有~昨天回复
点赞
1
tomcat学习笔记
qiao的博客
193
Url http://localhost:8080 在主页中可以进行一些基本的tomcat操作,而这些操作需要登录你的帐号密码,当然没有帐号密码可自行设置。 在/conf/tomcat-users.xml 可以进行设置。
Tomcat学习笔记(史上最全tomcat学习笔记)
fzdylfz的博客
360
Tomcat学习笔记(史上最全tomcat学习笔记) tomcat介绍 Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合…
tomcat学习记录_zhanglinlove的博客-CSDN博客
10-25
tomcat学习记录 服务器指接收请求数据并进行解析,完成相应的业务处理,然后把处理结果作为响应返回给请求的客户端。 tomcat中常用的设计模式有:模板方法模式,责任链模式…
TomCat学习笔记_记录博主学到的点滴-CSDN博客
9-16
TomCat学习笔记 把web工程部署到tomcat上 第一种方法:把工程的目录拷贝到tomcat的webapps目录下即可 第二种方法:找到tomcat下的conf目录Catalina\localhost写一个配置…
Tomcat学习笔记(一)
weixin_30845171的博客
64
Tomcat目录结构的认识   tomcat是Apache旗下的一个开源Servlet的容器,实现了对Servlet和JSP技术支持。 通过http://tomcat.apache.org/下载tomcat,解压可以看到目录结构如下:    下面对目录结构的进行分析。 bin:存在是可执行文件。在window下使用startup.bat和shu…
Tomcat和Http学习笔记
11-24
Tomcat服务器和Http协议学习笔记
Tomcat学习记录_weixin_45002019的博客-CSDN博客
8-17
Tomcat学习记录 Tomcat服务器 来自度娘的介绍 Tomcat在Idea配置 路径选择的本地下载好的Tomcat位置 配置Tomcat服务器在Idea中存在打开/关闭…
Tomcat学习记录_weixin_42779634的博客-CSDN博客
2-29
Tomcat学习记录本周进行了一个tomcat的学习,记录一下1、 Tomcat部署应用有几种方式,
Tomcat 学习笔记
Leo的博客
2331
概述Tomcat 是一开源的 Java Web 服务器,是当今最流行的基于 Java 的 Web 应用服务器。Tomcat 具有以下特点: Apache软件基金会出口 开源软件 源代码是Java写的 由于Tomcat 是使用Java语言实现的,因此Tomcat 的运行依赖于 Java 运行环境,故运行 Tomcat 前需要正确安装 JRE(Java Runtime Environment)。安装可以
JavaWeb学习笔记(二)——Tomcat学习
aliyacl的博客
546
一、Tomcat的配置文件 tomcat所有的配置文件放在conf文件夹中,其中核心配置文件是server.xml 1.更改Tomcat服务器启动端口 vi /tomcat/conf/server.xml 【注】一旦更改server.xml,必须重启服务 更改端口后也必须以新的端口去访问(假如把原先默认的端口8080改为8081):http://localhost:8081/ 二、…
Tomcat学习记录 - CSDN博客
9-23
1、结构 2、配置文件 server.xml配置 server标签 port:指定一个端口,这个端口负责监听关闭tomcat的请求。 shutdown:指定向端口发送的命令字符串。 service标签 name…
Tomcat学习笔记1_maijiecao的博客-CSDN博客
10-24
Tomcat学习 tomcat:支持http协议的工具,实现了servelet, jsp ,能让后端开发专注在服务上,提高开发效率,而不是协议交互上(交互的步骤十分重复) …
Tomcat的学习笔记
霍增光的博客
223

CSDN开发助手,集成开发者常用工具,提升开发效率
支持本地书签、tab页、历史记录搜索; 集成CSDN搜索结果; 他是一个时间转换工具; 他是一个计算器; 他是。。。,更多功能正在添加中
Tomcat学习笔记_weixin_45212025的博客-CSDN博客
10-24
Tomcat是属于阿帕奇基金会的开源软件,用于中小型的Javaweb项目,满足一部分JavaEE规范 阿帕奇基金会的开源软件,根目录都类似,所以要学习一下 …
Tomcat学习记录 - happyzara的博客 - CSDN博客
11-26
Tomcat学习记录 2013年08月06日 20:52:43 happyzara 阅读数:1 Tomcat处理HTTP请求源码分析:[url]http://www.infoq.com/cn/articles/zh-tomcat-http-request-1…
TOMCAT学习笔记
studyvcmfc的专栏
666
TOMCAT学习笔记 (2011-10-03 17:03:26) 转载▼ 标签: 杂谈 分类: 编程 2011年10月3日 1.TOMCAT总体来说由两部分组成:connector和container。 connector主要功能是:为每个接收到的HTTP请求(处理请求类:解析请求)建立request对象和response对象。
tomcat学习笔记-Java文档类资源
10-28
Tomcat学习笔记(史上最全tomcat学习笔记) 344Tomcat学习笔记(史上最全tomcat学习笔记) tomcat介绍Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目…
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
关于我们
招贤纳士
广告服务
开发助手

400-660-0108

kefu@csdn.net

在线客服
工作时间 8:30-22:00
公安备案号11010502030143
京ICP备19004658号
京网文〔2020〕1039-165号
经营性网站备案信息
北京互联网违法和不良信息举报中心
网络110报警服务
中国互联网举报中心
家长监护
Chrome商店下载
©1999-2020北京创新乐知网络技术有限公司
版权与免责声明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个 SQL 语句,用于向借阅表中插入数据。该表包含以下字段:借阅编号、读者编号、书籍编号、借阅日期、归还日期、借阅状态。每条数据表示一次借阅记录。其中借阅编号、读者编号、书籍编号、借阅日期和借阅状态是必填项,归还日期为可选项,如果借阅状态为“已还”则必须填写归还日期。 具体插入的数据如下: - 借阅编号:100001,读者编号:123413,书籍编号:0001,借阅日期:2020-11-05,归还日期:NULL,借阅状态:借阅 - 借阅编号:100002,读者编号:223411,书籍编号:0002,借阅日期:2020-9-28,归还日期:2020-10-13,借阅状态:已还 - 借阅编号:100003,读者编号:321123,书籍编号:1001,借阅日期:2020-7-01,归还日期:NULL,借阅状态:过期 - 借阅编号:100004,读者编号:321124,书籍编号:2001,借阅日期:2020-10-09,归还日期:2020-10-14,借阅状态:已还 - 借阅编号:100005,读者编号:321124,书籍编号:0001,借阅日期:2020-10-15,归还日期:NULL,借阅状态:借阅 - 借阅编号:100006,读者编号:223411,书籍编号:2001,借阅日期:2020-10-16,归还日期:NULL,借阅状态:借阅 - 借阅编号:100007,读者编号:411111,书籍编号:1002,借阅日期:2020-9-01,归还日期:2020-9-24,借阅状态:已还 - 借阅编号:100008,读者编号:411111,书籍编号:0001,借阅日期:2020-9-25,归还日期:NULL,借阅状态:借阅 - 借阅编号:100009,读者编号:411111,书籍编号:1001,借阅日期:2020-10-08,归还日期:NULL,借阅状态:借阅

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值