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 ...
随机推荐
- Goldwave-5.7[逆向流程+算法分析]
目标程序:Goldwave 5.7 分析工具: 1.OllyDbg 2.IDAPro 目的:用C语言写Goldwave-5.7的注册机. 0x0思路: 1.注册机准备: 功能:输入用户名后经过计算输出 ...
- centos 6.5升级openssl
1.下载升级版本 wget https://www.openssl.org/source/openssl-1.1.0i.tar.gz 2.安装 zlib zlib-devel yum -y insta ...
- 查询树节点、oracle、select...start with...connect by prior...
通过子节点向根节点追朔. select * from persons.dept start with deptid=76 connect by prior paredeptid=deptid 通过根节 ...
- enumerate的用法
names = ["tony","huluwa","tom","jerry","lala"]for ...
- Java学习之JDBC 2019/3/10
Java学习之JDBC 大部分的程序都是用来通过处理数据来达到人们预期的效果,数据是粮食,没有数据操作的程序就像helloworld程序一样没有用处.因此数据库操作是重中之重,是程序发挥功能的基石,j ...
- Python机器学习步骤
推荐学习顺序 学习机器学习得有个步骤, 下面大家就能按照自己所需, 来探索这个网站. 图中请找到 "Start", 然后依次沿着箭头, 看看有没有不了解/没学过的地方, 接着, 就 ...
- “PurMVC”在Unity中的应用
序章: 这是"游戏设计进阶技巧篇"内容,游戏中不使用如下技巧也可以正常运行,但是有了它以后可以增加项目的可读性,使功能”模块化“,”可视化“,”装逼化“(慢慢的恶意>,> ...
- 常用类:Object
2017-08-08 Object :作为所有类的根类,(超类,父类) 常用的方法: public int hasCode(){//返回该对象的哈希码值(地址)}:判断对象是否在同一内存地址上 pub ...
- Senparc.Weixin SDK v5.0 升级公告
经过五年半的持续维护,Senparc.Weixin SDK 逐步丰满和完善,在升级的过程中,我们为基础库(Senparc.Weixin.dll)加入了许多通用的功能,例如加密/解密算法.通用缓存方法等 ...
- C/C++ 多线程机制
一.C/C++多线程操作说明 C/C++多线程基本操作如下: 1. 线程的建立结束 2. 线程的互斥和同步 3. 使用信号量控制线程 4. 线程的基本属性配置 在C/C++代码编写时,使用多线程机制, ...