Tomcat8源码笔记(五)组件Container分析
Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的?
说到Container的初始化,Tomcat8源码笔记(三)Catalina加载过程 这篇文章记录了Tomcat是怎样解析server.xml的流程,再此基础上,我们来分析Container的初始化。
这是Catalina定义的解析规则,之前都是添加的Rule接口的实现,而RuleSet可以理解为一堆Rule更具象的接口;而各种各样的Rule作用是啥,目的就是解析server.xml时候,按照规则来解析并且生成有结构的对象。

Digester的addRuleSet方法:
因为Tomcat server.xml没有用到DTD XSD文件声明元素,所以namespaceURI都是null(我是这样理解的),所以添加RuleSet类型的规则实际上是调用ruleSet的addRuleInstances方法.那就来记录下EngineRuleSet的addRuleInstances方法。

Engine元素规则
这些规则ObjectCreate、SetProperties、SetNext分别有啥用,Tomcat8源码笔记(三)Catalina加载过程 这里就不多介绍了;
可以得出以下结论:Engine的实例化对象为StandardEngine,StandardEngine会有第一个监听器,EngineConfig,如果哪天不想添加EngineConfig作为第一个默认的监听器,方法也是可以的,修改Engine元素的engineConfigClass即可; 我们可给Engine元素添加这些子元素达到扩展的目的:Cluster、Listener、Valve、Realm,;
其实总结下来就是,Engine容器具体实例化对象为StandardEngine,且天生自带监听器EngineConfig,且Engine的父容器就是StandardService

按照 Tomcat8源码笔记(三)Catalina加载过程 的说明,只是将StandardService调用了setContainer关联了StandardEngine,那是不是就像 Service是父母,而Engine是婴儿,父母知道婴儿是谁,但是婴儿却不知道父母是谁呢? 为了让Container容器知道父类Service是谁,实现方案也很简单:
Tomcat在给Service设置容器的时候,顺便双向关联了Engine,这里也能看出来,Tomcat结构中Service的容器就是Engine!

其他属性先忽略,验证下我们得到的结论: 注意service以及lifecycleListener,可以验证我们上面的分析。

StandardEngine容器初始化
按照之前 Tomcat8源码笔记(四)Server和Service初始化 分析的来看,StandardEngine初始化initInternal核心方法调用之前,触发监听器的before_init事件!

当然了 StandardEngine目前的listener也就是EngineConfig,它触发时间仅仅针对 StandardEngine的start、stop方法才做逻辑处理,所以此处忽略其触发监听器before_init和after_init事件

那StandardEngine初始化的真正方法initInternal做了什么处理?
getRealm方法只是为了确保realm属性的存在,哪怕没有Realm子元素,我也给你一个NullRealm;
super.initInternal在抽象类LifecycleMBeanBase的子类中,调用父类initInternal,是为了JMX注册,比如StandardEngine、StandardService都是为了JMX注册;
而到了容器这里,super.initInternal又进行了额外的处理,可以看成是容器特有的,和服务区分开来。

IDEA给我们绘制的Tomcat组件结构中,可以看到LifecycleMBeanBase子类又抽象出ContainerBase,ContainerBase的initInternal方法又是一番逻辑!

ContainerBase的initInternal
可以看到初始化了一个ThreadPoolExecutor,corePoolSize和maxPoolSize默认都是1,线程名字前缀为getName()+”-startStop-”,比如StandardEngine,线程名字就是
Catalina-startStop-1这种模式。 之后才是用父类LifecycleMBeanBase的initInternal注册JMX中.

继续回到StandardService的初始化,Tomcat8源码笔记(四)Server和Service初始化 container已经初始化完毕,而executor、mapperListener的初始化工作除了JMX之外,没任何操作了,这两个组件真正起作用是在start启动中;后面文章就以Tomcat核心组件Connector初始化来分析。

补充于2019.4.9
StandardEngine的实例化,这么重要的居然忘记记录了!
Tomcat中容器的实例化基本都是通过空参构造器反射实例化,暂时未见到例外;查看StandardEngine的空参构造器

这里就不得不记录一个重要的接口Pipeline的分析
Pipeline接口所有方法围绕着Valve和Container有关,

Valve接口
Valve接口有点像链表,我可以获取我下一个指向的链表; Valve接口还定义了invoke方法; 按照英语翻译Valve是阀门的意思,而Pipeline是管道的意思;

上面接口介绍有点抽象,直接来看下StandardEngine中的管道和阀门吧; 首先pipeline的初始化不是在StandardEngine中,而是在ContainerBase中:实例化Pipeline实现类,并且调用setContainer将容器和Pipeline关联在一起。

而StandardEngine初始化过程中就使用了pipeline.setBasic方法,我们来看下setBasic方法:
setBasic方法设置了pipeline的basic,并且如果原来pipeline存在first,first下一个指向原来的basic,那现在basic是新添加的valve,且原来的basic的next就是添加进来的valve.

Tomcat8源码笔记(五)组件Container分析的更多相关文章
- Tomcat8源码笔记(七)组件启动Server Service Engine Host启动
一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...
- Tomcat8源码笔记(六)连接器Connector分析
根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...
- Tomcat8源码笔记(九)组件StandardContext启动流程--未完待续
StandardContext代表的是webapps下项目,一个项目就是一个StandardContext,作为Tomcat组件的一部分,就会实现Lifecycle接口,被Tomcat管理着生命周期, ...
- Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目
以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...
- Tomcat8源码笔记(三)Catalina加载过程
之前介绍过 Catalina加载过程是Bootstrap的load调用的 Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...
- Tomcat8源码笔记(四)Server和Service初始化
上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...
- Tomcat8源码笔记(一)Lifecycle接口
第一次阅读Tomcat8源码,就以Lifecycle作为笔记阅读的开篇吧,一千个读者就有一千个哈姆雷特,每个人都Tomcat的理解都不同,如果不记录一次Tomcat源码可能忘了就忘了. 断断DEBUG ...
- Tomcat8源码笔记(二)Bootstrap启动
TOMCAT源码调试入口是Bootstrap类的main方法,我的启动参数VM: -Dcatalina.home=E:/Tomcat_Source_Code/apache-tomcat-8.0.53- ...
- Django-restframework 源码之认证组件源码分析
Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...
随机推荐
- redis学习-集合set常用命令
redis学习-集合set常用命令 1.sadd:添加一个元素到集合中(集合中的元素无序的并且唯一) 2.smembers:查看集合中所有的元素(上图事例) 3.srem:删除结合中指定的元素 4 ...
- CentOS6.8手动安装MySQL5.6(转)
1.安装mysql5.6依存包 2.下载编译包 wget https://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.35-linux-glibc2 ...
- Centos6.5 安装MYSQL 5.5 -5.6.-5.7 一键yum快速安装 ,初始配置
Centos6.5 安装MYSQL 5.5 ---5.6---5.7 一键yum快速安装 ,初始配置 第一步:安装mysql-5.5---- 5.6 ---- 5.7的yum源 [root@sv03 ...
- VSCode插件开发全攻略(八)代码片段、设置、自定义欢迎页
更多文章请戳VSCode插件开发全攻略系列目录导航. 代码片段 代码片段,也叫snippets,相信大家都不陌生,就是输入一个很简单的单词然后一回车带出来很多代码.平时大家也可以直接在vscode中创 ...
- mvc网站迁移.net core记录
接口return Json()时序列号小写的问题 在Startup.cs->ConfigureServices方法配置一下解决 public void ConfigureServices(ISe ...
- 【渗透攻防】深入了解Windows
前言 本篇是基础教程,带大家了解Windows常用用户及用户组,本地提取用户密码,远程利用Hash登录到本地破解Hash.初步掌握Windows基础安全知识. 目录 第一节 初识Windows 第二节 ...
- 吴恩达机器学习笔记13-正规方程(Normal Equation)
到目前为止,我们都在使用梯度下降算法,但是对于某些线性回归问题,正规方程方法是更好的解决方案.如: 即: 运用正规方程方法求解参数: 注:对于那些不可逆的矩阵(通常是因为特征之间不独立,如同时包含英尺 ...
- 《http权威指南》读书笔记11
概述 最近对http很感兴趣,于是开始看<http权威指南>.别人都说这本书有点老了,而且内容太多.我个人觉得这本书写的太好了,非常长知识,让你知道关于http的很多概念,不仅告诉你怎么做 ...
- CSS揭秘—多重边框(二)
前言: 所有实例均来自<CSS揭秘>,该书以平时遇到的疑难杂症为引,提供解决方法,只能说秒极了,再一次刷新了我对CSS的认知 该书只提供了关键CSS代码,虽然有在线示例代码链接,但访问速度 ...
- Metasploit Framework(3)Meterpreter
文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 Meterpreter:是一种高级的,动态的,可拓展的 ...