Tomcat学习小记(二)
1、Tomcat源码入口
生命周期统一管理接口:LifeCycle

实现LifeCycle接口的类:(idea快捷键:Ctrl+h)
多个组件共同实现LifeCycle接口

Tomcat启动入口分析:
(1)根据不同的操作系统,找到启动脚本,startup.bat/startup.sh,我用的是windows操作系统,用的是startup.bat
startup.bat脚本最后执行函数,执行一个EXECUTABLE变量代表的函数(通过startup.bat去调用catalina.bat脚本),并向函数中传入start参数


(2)catalina.bat脚本中搜索传入的参数"start"

可以看到要去执行dostart函数,最后找到tomcat是由org.apache.catalina.startup.Bootstrap.main()启动的

CATALINA_BASE: D:\Tomcat\apache-tomcat-8.5.9
CATALINA_HOME: D:\Tomcat\apache-tomcat-8.5.9
Command line argument: -Djava.util.logging.config.file=D:\Tomcat\apache-tomcat-8.5.9\conf\logging.properties
Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
Command line argument: -Dcatalina.base=D:\Tomcat\apache-tomcat-8.5.9
Command line argument: -Dcatalina.home=D:\Tomcat\apache-tomcat-8.5.9
Command line argument: -Djava.io.tmpdir=D:\Tomcat\apache-tomcat-8.5.9\temp
(3)启动类BootStrap,加载初始化以及启动
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();//初始化
} 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);
}
}
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);//加载初始化,一级一级初始化(对象的实例),connector组件endpoint(socket通信端口bind,尚未accept)
daemon.start();//启动,一级一级启动(开始accept接收请求)
if (null == daemon.getServer()) {
System.exit(1);
}
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else if (command.equals("configtest")) {
daemon.load(args);
if (null == daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
// Unwrap the Exception for clearer error reporting
if (t instanceof InvocationTargetException &&
t.getCause() != null) {
t = t.getCause();
}
handleThrowable(t);
t.printStackTrace();
System.exit(1);
}
}
2、Tomcat初始化
daemon.load(args);//加载初始化,一级一级初始化(对象的实例),connector组件endpoint(socket通信端口bind,尚未accept)
通过load方法通过反射调用catalina.load()方法
catalina.load()方法中调用digester.parse(inputSource)去解析server.xml文件
通过得到的server对象调用init()方法去初始化
init()方法实现LifecycleBase接口的init()方法,LifecycleBase接口的init()方法去调用LifecycleBase.initInternal()方法,而LifecycleBase.initInternal()方法是一个抽象方法,所以具体实现都是在子类中
//使用了模板方法设计模式,在父类中规定执行的步骤,而其中的某些步骤的实现都是在子类中实现
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
} try {
setStateInternal(LifecycleState.INITIALIZING, null, false);
//init关键之处,实现子类是standardServer类中
initInternal();
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.initFail", toString());
}
}
standardServer.initInternal()子类中递归调用StandardService.init()方法,对servlet容器和连接器组件进行初始化,后续组件一级一级循环调用,一级一级进行初始化,逻辑相同
for (int i = 0; i < services.length; i++) {
services[i].init();
}

3、Tomcat启动
启动流程和初始化相似

4、Servlet请求分析
servlet请求——>找到处理servlet实例——>servlet.service()
connect组件接收servlet请求,并传递到servlet容器中——>Engine引擎根据url找到处理servlet的实例

5、Servlet请求处理步骤
请求入口类:NioEndpoint类
NioEndpoint.Poller(),检查是否有可以被处理的socket请求
NioEndpoint.startAcceptorThreads(),用来接收请求的线程

Tomcat学习小记(二)的更多相关文章
- Tomcat 学习笔记二
学习一 java.bean.PropertyChangeListener用来监听bean类的属性值改变.当改变时同时执行对应事件.而且是线程安全的.tomcat用此reload的Boolean值改变是 ...
- Tomcat学习之二:tomcat安装、配置及目录文件说明
我们看到tomcat目录/bin文件夹里有个tomcat6w.exe,顾名思义就是tomcat以window方式显示控制台.第1次点击打开它时候,可能会提示:tomcat指定的服务未安装,此时我们可以 ...
- Tomcat学习笔记(二)
Servlet浅析 javax.servlet.Servlet是一个接口,所有的Servlet必须实现接口里面的方法. 该接口在tomcat/bin中的servlet-api.jar包中. Servl ...
- Tomcat学习小记(一)
1.Tomcat概述 Tomcat 服务器是一个开源的轻量级Web应用服务器,擅长处理动态资源,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet.JSP 程序的首选. Tomcat ...
- Tomcat剖析(二):一个简单的Servlet服务器
Tomcat剖析(二):一个简单的Servlet服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三) ...
- Gcd&Exgcd算法学习小记
Preface 对于许多数论问题,都需要涉及到Gcd,求解Gcd,常常使用欧几里得算法,以前也只是背下来,没有真正了解并证明过. 对于许多求解问题,可以列出贝祖方程:ax+by=Gcd(a,b),用E ...
- Shell 学习(二)
目录 Shell 学习(二) 1 设置环境变量 1.1 基本语法 1.2 实践 2 位置参数变量 2.1 介绍 2.2 基本语法 2.3 位置参数变量应用实例 3 预定义变量 3.1 基本介绍 3.2 ...
- crawler4j 学习(二)
crawler4j 学习(二) 实现控制器类以制定抓取的种子(seed).中间数据存储的文件夹.并发线程的数目: public class Controller { public static voi ...
- mongodb入门学习小记
Mongodb 简单入门(个人学习小记) 1.安装并注册成服务:(示例) E:\DevTools\mongodb3.2.6\bin>mongod.exe --bind_ip 127.0.0.1 ...
随机推荐
- 创建human用户登录数据库创建表
根据人力资源管理系统中表的设计,创建human用户登录数据库创建 准备阶段 把运行脚本复制到D:\app\Administrator\product\11.2.0\dbhome_1\demo\sche ...
- rbac表 ( 5张 )
/* Navicat Premium Data Transfer Source Server : 本地连接 Source Server Type : MySQL Source Server Versi ...
- Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 3.使用 Subscriber 控制发布速度. 内容概览 前言 在发布者生产元素时消耗它们 使 ...
- Javascript常见数据类型API
1 - 内置对象 1.1 内置对象 JavaScript 中的对象分为3种:自定义对象 .内置对象. 浏览器对象 前面两种对象是JS 基础 内容,属于 ECMAScript: 第三个浏览器对象 ...
- 入门的艰难——关于LR的使用
这年头做一件事真是TM不容易啊.做测试也很纠结,不是都说商业工具很强大么,我去,这个不支持那个不支持的,这还有什么搞头,还非要按照你说的这个版本的才行,高一点的就crash了,结果连最初级的录制脚本都 ...
- 目标识别AI资料
朋友推荐的, 还有自己搜的. 入门可以看看. 网上资料应该不少, 一搜一大把, 简单记下地址. Review of Deep Learning Algorithms for Object Detect ...
- HashMap源码解析、jdk7和8之后的区别、相关问题分析(多线程扩容带来的死循环)
一.概览 HashMap<String, Integer> map = new HashMap<>(); 这个语句执行起来,在 jdk1.8 之前,会创建一个长度是 16 的 ...
- Python之 最全 Conda、pip 管理环境和安装包、更换源、解决HttpError等一些列问题
在Anaconda中conda可以理解为一个工具,也是一个可执行命令,其核心功能是环境管理与包管理.所以对虚拟环境进行创建.删除等操作需要使用conda命令. conda install 和 pip ...
- cdispaly的Grid布局与Flex布局
cdispaly的Grid布局与Flex布局 Gird 布局与 Flex 布局有一定的相似性,都是对容器的内部项目进行划分. Flex 布局是轴线布局,只能指定项目针对轴线的位置,可以看作成一维布局 ...
- fabric1.4 网络操作
建立第一个网络 进入对应目录 $ cd fabric-samples/first-network 在first-network目录下有两个自动化脚本byfn.sh和eyfn.sh, 这两个脚本的启动顺 ...