当前位置: 首页 > news >正文

Tomcat源码分析-启动分析(二) Catalina初始化

Bootstrap

Tomcat运行是通过Bootstrap的main方法,在开发工具中,我们只需要运行Bootstrap的main方法,便可以启动tomcat进行代码调试和分析。Bootstrap是tomcat的入口,它会完成初始化ClassLoader,实例化Catalina以及load、start动作。在这一篇文章中,我们将会对tomcat初始化过程进行分析。

main方法

首先实例化Bootstrap,并调用init方法对其初始化

Bootstrap bootstrap = new Bootstrap();

init

首先初始化commonLoader、catalinaLoader、sharedLoader,默认情况下这三个是相同的实例,用于加载不同的资源。然后,使用反射实例化Catalina,设置其parentClassLoader为sharedLoader

public void init() throws Exception {// 初始化commonLoader、catalinaLoader、sharedLoader,关于ClassLoader的后面再单独分析initClassLoaders();Thread.currentThread().setContextClassLoader(catalinaLoader);SecurityClassLoad.securityClassLoad(catalinaLoader);// 反射方法实例化Catalina,后面初始化Catalina也用了很多反射,不知道意图是什么Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");Object startupInstance = startupClass.getConstructor().newInstance();// 反射调用setParentClassLoader方法,设置其parentClassLoader为sharedLoaderString methodName = "setParentClassLoader";Class<?> paramTypes[] = new Class[1];paramTypes[0] = Class.forName("java.lang.ClassLoader");Object paramValues[] = new Object[1];paramValues[0] = sharedLoader;Method method =startupInstance.getClass().getMethod(methodName, paramTypes);method.invoke(startupInstance, paramValues);// 引用Catalina实例catalinaDaemon = startupInstance;

load & start

初始化Bootstrap之后,接下来就是加载配置,启动容器。而load、start实际上是由Bootstrap反射调用Catalina的load、start,这一部分代码将在下面的Catalina部分进行分析

  • 启动时,Catalina.setAwait(true),其目的是为了让tomcat在关闭端口阻塞监听关闭命令,参考Catalina.await()方法
  • deamon.load(args),实际上会去调用Catalina#load(args)方法,会去初始化一些资源,优先加载conf/server.xml,找不到再去加载server-embed.xml;此外,load方法还会初始化Server
  • daemon.start(),实例上是调用Catalina.start()
// daemon即Bootstrap实例
daemon.setAwait(true);
daemon.load(args);

Catalina

由前面的分析,可知Bootstrap中的load逻辑实际上是交给Catalina去处理的,下面我们对Catalina的初始化过程进行分析

load(init)

load阶段主要是通过读取conf/server.xml或者server-embed.xml,实例化Server、Service、Connector、Engine、Host等组件,并调用Lifecycle#init()完成初始化动作,以及发出INITIALIZING、INITIALIZED事件

1、 首先初始化jmx的环境变量
2、 定义解析server.xml的配置,告诉Digester哪个xml标签应该解析成什么类,如果我们要改变server.xml的某个属性值(比如优化tomcat线程池),直接查看对应实现类的setXXX方法即可
3、 解析conf/server.xml或者server-embed.xml,并且实例化对应的组件并且赋值操作,比如Server、Container、Connector等等
4、 为Server设置catalina信息,指定Catalina实例,设置catalina的home、base路径
5、 调用StarndServer#init()方法,完成各个组件的初始化,并且由parent组件初始化child组件,一层套一层,这个设计真心牛逼!

public void load() {initDirs();// 初始化jmx的环境变量initNaming();// Create and execute our Digester// 定义解析server.xml的配置,告诉Digester哪个xml标签应该解析成什么类Digester digester = createStartDigester();InputSource inputSource = null;InputStream inputStream = null;File file = null;try {// 首先尝试加载conf/server.xml,省略部分代码......// 如果不存在conf/server.xml,则加载server-embed.xml(该xml在catalina.jar中),省略部分代码......// 如果还是加载不到xml,则直接return,省略部分代码......try {inputSource.setByteStream(inputStream);// 把Catalina作为一个顶级实例digester.push(this);// 解析过程会实例化各个组件,比如Server、Container、Connector等digester.parse(inputSource);} catch (SAXParseException spe) {// 处理异常......}} finally {// 关闭IO流......}// 给Server设置catalina信息getServer().setCatalina(this);getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());// Stream redirectioninitStreams();// 调用Lifecycle的init阶段try {getServer().init();} catch (LifecycleException e) {// ......}// ......

load时序图如下所示(查看原图):

  • Digester利用jdk提供的sax解析功能,将server.xml的配置解析成对应的Bean,并完成注入,比如往Server中注入Service
  • EngineConfig,它是一个LifecycleListener实现,用于配置Engine,但是只会处理START_EVENT和STOP_EVENT事件
  • Connector默认会有两种:HTTP/1.1、AJP,不同的Connector内部持有不同的CoyoteAdapter和ProtocolHandler,在Connector初始化的时候,也会对ProtocolHandler进行初始化,完成端口的监听
  • ProtocolHandler常用的实现有Http11NioProtocol、AjpNioProtocol,还有apr系列的Http11AprProtocol、AjpAprProtocol,apr系列只有在使用apr包的时候才会使用到
  • 在ProtocolHandler调用init初始化的时候,还会去执行AbstractEndpoint的init方法,完成请求端口绑定、初始化NIO等操作,在tomcat7中使用JIoEndpoint阻塞IO,而tomcat8中直接移除了JIoEndpoint,具体信息请查看org.apache.tomcat.util.net这个包

Catalina在load结束之前,会调用Server的init()完成各个组件的初始化,下面我们来分析下各个组件在init初始化过程中都做了哪些操作

相关文章:

Tomcat源码分析-启动分析(二) Catalina初始化

Bootstrap Tomcat运行是通过Bootstrap的main方法&#xff0c;在开发工具中&#xff0c;我们只需要运行Bootstrap的main方法&#xff0c;便可以启动tomcat进行代码调试和分析。Bootstrap是tomcat的入口&#xff0c;它会完成初始化ClassLoader&#xff0c;实例化Catalina以及loa…...

基础复习第二十二天 泛型的使用

泛型JDK1.5设计了泛型的概念。泛型即为“类型参数”&#xff0c;这个类型参数在声明它的类、接口或方法中&#xff0c;代表未知的通用的类型。例如&#xff1a;java.lang.Comparable接口和java.util.Comparator接口&#xff0c;是用于对象比较大小的规范接口&#xff0c;这两个…...

【C++进阶】三、二叉搜索树

目录 一、二叉搜索树 1.1 概念 1.2 二叉搜索树操作 二、二叉搜索树实现 2.1 框架总览 2.2 实现接口总览 2.2.1 构造函数 2.2.2 拷贝构造 2.2.3 赋值重载 2.2.4 析构函数 2.2.5 二叉搜索树的遍历 2.2.6 插入函数 2.2.7 查找函数 2.2.8 删除函数 2.3 二叉搜索数完整…...

电脑系统崩溃怎么修复教程

系统崩溃了怎么办? 如今的软件是越来越复杂、越来越庞大。由系统本身造成的崩溃即使是最简单的操作&#xff0c;比如关闭系统或者是对BIOS进行升级都可能会对PC合操作系统造成一定的影响。下面一起来看看电脑系统崩溃修复方法步骤。 工具/原料&#xff1a; 系统版本&#xf…...

语义分割数据标注案例分析

语义分割&#xff08;Semantic Segmentation&#xff09;是计算机视觉领域中的一种重要任务&#xff0c;它的目的是将图像中的每个像素分配到对应的语义类别中。简单来说&#xff0c;就是将一张图像分割成多个区域&#xff0c;并为每个像素指定一个标签&#xff0c;标识出它属于…...

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(多指标评价)

回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(多指标评价) 文章目录 回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出(多指标评价)预测效果基本介绍程序设计参考资料预测效果 基本介绍 GRU神经网络是LST...

驱动程序开发:Buildroot根文件系统构建并加载驱动文件xxx.ko测试

目录一、buildroot根文件系统简介二、buildroot下载三、buildroot构建根文件系统1、配置 buildroot①配置 Target options②配置 Toolchain③配置 System configuration④配置 Filesystem images⑤禁止编译 Linux 内核和 uboot2、 buildroot 下的 busybox 配置①修改 Makefile&…...

R+VIC模型融合实践技术应用及未来气候变化模型预测

目录 理论专题一&#xff1a;VIC模型的原理及特点 综合案例一&#xff1a;基于QGIS的VIC模型建模 理论专题二&#xff1a;VIC模型率定验证 综合案例二&#xff1a;基于R语言VIC参数率定和优化 理论专题三&#xff1a;遥感技术与未来气候变化 综合案例三&#xff1a;运用V…...

第六章.决策树(Decision Tree)—ID3算法,C4.5算法

第六章.决策树(Decision Tree) 6.1 ID3算法,C4.5算法 1.决策树适用的数据类型 比较适合分析离散数据&#xff0c;如果是连续数据要先转换成离散数据再做分析 2.信息熵 1).概念&#xff1a; 一条信息的信息量大小和它的不确定性有直接的关系&#xff0c;要搞清楚一件非常不确…...

springboot+pgbouncer+postgres数据库连接池集成方案及问题解决

期望通过每一次分享&#xff0c;让技术的门槛变低&#xff0c;落地更容易。 —— around 前言 旨在解决微服务项目全是连接池并影响数据库并发连接&#xff0c;作者的环境是基于sprongboot微服务连接postgres数据库&#xff0c;每个微服务的DAO层配置都使用了连接池技术。后续…...

Mysql 常用日期处理函数

Mysql 常用日期处理函数 1 建表语句 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0; -- ---------------------------- -- Table structure for emp -- ---------------------------- DROP TABLE IF EXISTS emp; CREATE TABLE emp (EMPNO int(4) NOT NULL,ENAME varchar(10…...

Pod中容器的健康检查

健康检查 上篇文章中我们了解了Pod中容器的生命周期的两个钩子函数&#xff0c;PostStart与PreStop&#xff0c;其中PostStart是在容器创建后立即执行的&#xff0c;而PreStop这个钩子函数则是在容器终止之前执行的。除了上面这两个钩子函数以外&#xff0c;还有一项配置会影响…...

信贷系统学习总结(5)—— 简单的风控示例(含代码)

一、背景1.为什么要做风控?目前我们业务有使用到非常多的AI能力,如ocr识别、语音测评等,这些能力往往都比较费钱或者费资源,所以在产品层面也希望我们对用户的能力使用次数做一定的限制,因此风控是必须的!2.为什么要自己写风控?那么多开源的风控组件,为什么还要写呢?是不是想…...

Java知识复习(四)多线程、并发编程

1、进程、线程和程序 进程&#xff1a;进程是程序的一次执行过程&#xff0c;是系统运行程序的基本单位&#xff0c;因此进程是动态的&#xff1b;在 Java 中&#xff0c;当我们启动 main 函数时其实就是启动了一个 JVM 的进程&#xff0c;而 main 函数所在的线程就是这个进程…...

一个9个月测试经验的人,居然在面试时跟我要18K,我都被他吓到了····

2月初我入职了深圳某家创业公司&#xff0c;刚入职还是很兴奋的&#xff0c;到公司一看我傻了&#xff0c;公司除了我一个测试&#xff0c;公司的开发人员就只有3个前端2个后端还有2个UI&#xff0c;在粗略了解公司的业务后才发现是一个从零开始的项目&#xff0c;目前啥都没有…...

zigbee与WIFI同频干扰问题

zigbee与WIFI同频干扰 为了降低Wifi信道与Zigbee信道的同频干扰问题&#xff0c;Zigbee联盟在《Zigbee Home Automation Public Application Profile》中推荐使用11,14,15,19,20,24,25这七个信道。 为什么呢&#xff0c;我们看一下Wifi和Zigbee的信道分布。 WiFi带宽对干扰的…...

git拉取指定的单个或多个文件或文件夹

直接上步骤 初始化仓库 git init拉取远程仓库信息&#xff0c;省略号为仓库地址 git remote add -f origin http://****.git开启 sparse clone git config core.sparsecheckout true配置需要拉取的文件夹 有一个指定一个&#xff0c;有多个指定多个&#xff0c;路径写对即可&a…...

不是,到底有多少种图片懒加载方式?

一、也是我最开始了解到的 js方法&#xff0c;利用滚动事件&#xff0c;判断当时的图片位置是否在可视框内&#xff0c;然后进行渲染。 弊端&#xff1a;代码冗杂&#xff0c;你还要去监听页面的滚动事件&#xff0c;这本身就是一个不建议监听的事件&#xff0c;即便是我们做了…...

CAD坐标有哪些输入方式?来看看这些CAD坐标输入方式!

在CAD设计过程中&#xff0c;有时需要通过已知坐标点来画图&#xff0c;有时又需要通过已知角度和距离来画图&#xff0c;在这种情况下&#xff0c;由于已知条件不同&#xff0c;所以便需要用不同的方式来定位点。那么&#xff0c;你知道CAD坐标有哪些输入方式吗&#xff1f;本…...

铰链、弹簧,特殊的物理关节

title: 铰链、弹簧&#xff0c;特殊的物理关节 date: 2023-02-28T13:32:57Z lastmod: 2023-02-28T14:24:06Z 铰链关节&#xff08;Hinge Join&#xff09;组件 组件-Physics-Hinge Join Anchor 当物体挂载铰链组件以后&#xff0c;组件下Anchor等同于边长为1的立方体。当这…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...