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学习小记(二)的更多相关文章

  1. Tomcat 学习笔记二

    学习一 java.bean.PropertyChangeListener用来监听bean类的属性值改变.当改变时同时执行对应事件.而且是线程安全的.tomcat用此reload的Boolean值改变是 ...

  2. Tomcat学习之二:tomcat安装、配置及目录文件说明

    我们看到tomcat目录/bin文件夹里有个tomcat6w.exe,顾名思义就是tomcat以window方式显示控制台.第1次点击打开它时候,可能会提示:tomcat指定的服务未安装,此时我们可以 ...

  3. Tomcat学习笔记(二)

    Servlet浅析 javax.servlet.Servlet是一个接口,所有的Servlet必须实现接口里面的方法. 该接口在tomcat/bin中的servlet-api.jar包中. Servl ...

  4. Tomcat学习小记(一)

    1.Tomcat概述 Tomcat 服务器是一个开源的轻量级Web应用服务器,擅长处理动态资源,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet.JSP 程序的首选. Tomcat ...

  5. Tomcat剖析(二):一个简单的Servlet服务器

    Tomcat剖析(二):一个简单的Servlet服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三) ...

  6. Gcd&Exgcd算法学习小记

    Preface 对于许多数论问题,都需要涉及到Gcd,求解Gcd,常常使用欧几里得算法,以前也只是背下来,没有真正了解并证明过. 对于许多求解问题,可以列出贝祖方程:ax+by=Gcd(a,b),用E ...

  7. Shell 学习(二)

    目录 Shell 学习(二) 1 设置环境变量 1.1 基本语法 1.2 实践 2 位置参数变量 2.1 介绍 2.2 基本语法 2.3 位置参数变量应用实例 3 预定义变量 3.1 基本介绍 3.2 ...

  8. crawler4j 学习(二)

    crawler4j 学习(二) 实现控制器类以制定抓取的种子(seed).中间数据存储的文件夹.并发线程的数目: public class Controller { public static voi ...

  9. mongodb入门学习小记

    Mongodb 简单入门(个人学习小记) 1.安装并注册成服务:(示例) E:\DevTools\mongodb3.2.6\bin>mongod.exe --bind_ip 127.0.0.1 ...

随机推荐

  1. v-html渲染富文本图片宽高问题

    v-html渲染富文本v-html是用来渲染html的节点及字符串的,但是渲染后富文本里的图片宽高会溢出所在div的区域但是使用css直接给img是没有办法设置img的宽高的,需要使用深层级来给img ...

  2. 1、Entity Framework Core 3.1入门教程-概述和准备工作

    本文章是根据 微软MVP solenovex(杨旭)老师的视频教程编写而来,再加上自己的一些理解. 视频教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR ...

  3. Java 将Html转为PDF

    本文介绍如何在Java程序中将html文件转换成PDF文件.转换时,需要注意以下两点: 一.需要使用转换插件 可根据不同的系统来下载对应的插件,下载地址:windows-x86.zip, window ...

  4. 如何通过seo技术提高网站对用户的友好度

    http://www.wocaoseo.com/thread-129-1-1.html    今天的天气又是29度,眼看着满大街的人都穿着短袖和衬衣了,自己也再不能穿个厚厚的外套出去了,要不会被别人笑 ...

  5. 集成学习小结(RF、adaboost、xgboost)

    目录 回顾监督学习的一些要素 集成学习(学什么) bagging boosting 梯度提升(怎么学) GBDT Xgboost 几种模型比较 Xgboost 与 GBDT xgboost 和 LR ...

  6. 位运算处理字符大小写转换 - 关联Leetcode 709. 转成小写字母

    大写变小写.小写变大写 : 字符 ^= 32; 大写变小写.小写变小写 : 字符 |= 32; 小写变大写.大写变大写 : 字符 &= -33; 题目 实现函数 ToLowerCase(),该 ...

  7. Android开发java程序员常用代码,将字符串以逗号分别取出字符串String

    public class StringSplit { public static void main(String[] args) { String sourceStr = "1,2,3,4 ...

  8. android开发之java代码中字符串对比忽略大小写。java程序员必回,可用来比对验证码等问题

    比如:字符串a与字符串B对比,只需调用 a.equalsIgnoreCase(B);即可.很简单的一个方法.忽略大小写.

  9. android Studio(3.2.1) NDK配置

    1.创建as工程 2. 创建class类 3. 生成头文件 3.1 配置命令工具 添加工具: 配置工具: Program: $JDKPath$\bin\javah.exe Arugments:-d j ...

  10. CodeForces - 1114D-Flood Fill (区间dp)

    You are given a line of nn colored squares in a row, numbered from 11 to nn from left to right. The  ...