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分析的更多相关文章

  1. Tomcat8源码笔记(七)组件启动Server Service Engine Host启动

    一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...

  2. Tomcat8源码笔记(六)连接器Connector分析

    根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...

  3. Tomcat8源码笔记(九)组件StandardContext启动流程--未完待续

    StandardContext代表的是webapps下项目,一个项目就是一个StandardContext,作为Tomcat组件的一部分,就会实现Lifecycle接口,被Tomcat管理着生命周期, ...

  4. Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目

    以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...

  5. Tomcat8源码笔记(三)Catalina加载过程

    之前介绍过 Catalina加载过程是Bootstrap的load调用的  Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...

  6. Tomcat8源码笔记(四)Server和Service初始化

    上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...

  7. Tomcat8源码笔记(一)Lifecycle接口

    第一次阅读Tomcat8源码,就以Lifecycle作为笔记阅读的开篇吧,一千个读者就有一千个哈姆雷特,每个人都Tomcat的理解都不同,如果不记录一次Tomcat源码可能忘了就忘了. 断断DEBUG ...

  8. Tomcat8源码笔记(二)Bootstrap启动

    TOMCAT源码调试入口是Bootstrap类的main方法,我的启动参数VM: -Dcatalina.home=E:/Tomcat_Source_Code/apache-tomcat-8.0.53- ...

  9. Django-restframework 源码之认证组件源码分析

    Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...

随机推荐

  1. Goldwave-5.7[逆向流程+算法分析]

    目标程序:Goldwave 5.7 分析工具: 1.OllyDbg 2.IDAPro 目的:用C语言写Goldwave-5.7的注册机. 0x0思路: 1.注册机准备: 功能:输入用户名后经过计算输出 ...

  2. centos 6.5升级openssl

    1.下载升级版本 wget https://www.openssl.org/source/openssl-1.1.0i.tar.gz 2.安装 zlib zlib-devel yum -y insta ...

  3. 查询树节点、oracle、select...start with...connect by prior...

    通过子节点向根节点追朔. select * from persons.dept start with deptid=76 connect by prior paredeptid=deptid 通过根节 ...

  4. enumerate的用法

    names = ["tony","huluwa","tom","jerry","lala"]for ...

  5. Java学习之JDBC 2019/3/10

    Java学习之JDBC 大部分的程序都是用来通过处理数据来达到人们预期的效果,数据是粮食,没有数据操作的程序就像helloworld程序一样没有用处.因此数据库操作是重中之重,是程序发挥功能的基石,j ...

  6. Python机器学习步骤

    推荐学习顺序 学习机器学习得有个步骤, 下面大家就能按照自己所需, 来探索这个网站. 图中请找到 "Start", 然后依次沿着箭头, 看看有没有不了解/没学过的地方, 接着, 就 ...

  7. “PurMVC”在Unity中的应用

    序章: 这是"游戏设计进阶技巧篇"内容,游戏中不使用如下技巧也可以正常运行,但是有了它以后可以增加项目的可读性,使功能”模块化“,”可视化“,”装逼化“(慢慢的恶意>,> ...

  8. 常用类:Object

    2017-08-08 Object :作为所有类的根类,(超类,父类) 常用的方法: public int hasCode(){//返回该对象的哈希码值(地址)}:判断对象是否在同一内存地址上 pub ...

  9. Senparc.Weixin SDK v5.0 升级公告

    经过五年半的持续维护,Senparc.Weixin SDK 逐步丰满和完善,在升级的过程中,我们为基础库(Senparc.Weixin.dll)加入了许多通用的功能,例如加密/解密算法.通用缓存方法等 ...

  10. C/C++ 多线程机制

    一.C/C++多线程操作说明 C/C++多线程基本操作如下: 1. 线程的建立结束 2. 线程的互斥和同步 3. 使用信号量控制线程 4. 线程的基本属性配置 在C/C++代码编写时,使用多线程机制, ...