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 ...
随机推荐
- vimrc备份
备份一下我的 gvim 配置文件 " 使vimrc文件立马生效 autocmd BufWritePost $MYVIMRC source $MYVIMRC " 设置自己的Leade ...
- Linux离线安装mysql 5.6详细步骤
一.安装MySQL 1.下载安装包 mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz 2.卸载系统自带的Mariadb rpm -qa|grep mariadb / ...
- seo成功案例的背后秘密
http://www.wocaoseo.com/thread-319-1-1.html 刚刚在seo群内一个企业主告诉我,他在淘宝找了做seo排名的,在交了首付后,对方却跑路了.对方刚刚在淘宝开店,然 ...
- [ASP.NET Core开发实战]基础篇06 配置
配置,是应用程序很重要的组成部分,常常用于提供信息,像第三方应用登录钥匙.上传格式与大小限制等等. ASP.NET Core提供一系列配置提供程序读取配置文件或配置项信息. ASP.NET Core项 ...
- 【Android】listview 嵌套gridview报错,代码:”during second layout pass: posting in next frame
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 公众号:程序员小冰 说明:本人曾经在listview嵌套gridview出现 ...
- Android开发之常用框架WebView详解代码。超详细,送给初学者,完全掌握此控件
这是我特意为新手小白写的一个代码,教大家完完全全掌握WebView, 我感觉,你看懂这个,基本上可以满足以后工作中的需要了,(只针对Webview的使用),但是其实它还有好多功能,比如真正的设计到和H ...
- EventDispatcher
事件分发类,提供事件注册.移除.触发功能 采用delegate.dictionary实现 支持自定义事件.事件采用字符串方式标识 支持 0,1,2,3,4 等5种不同参数个数的回调函数 // 路由 ...
- C++从LPEXCEPTION_POINTERS获取调用堆栈
#pragma once #include <map> #include <vector> struct FunctionCall { DWORD64 Address; std ...
- sort(桶排序+hash)
题目链接:https://cn.vjudge.net/problem/HDU-1425 注意是多组输入 代码: #include<cstdio> #include<iostream& ...
- CTF常见源码泄漏总结
.hg源码泄漏 漏洞成因: hg init的时候会生成.hge.g.http://www.am0s.com/.hg/ 漏洞利用:工具:dvcs-ripperrip-hg.pl -v -u http:/ ...