当前位置: 首页 > 编程日记 > 正文

How Tomcat works — 四、tomcat启动(3)

上一节说到StandardService负责启动其子组件:container和connector,不过注意,是有先后顺序的,先启动container,再启动connector,这一节先来看看container。

目录

  • Pipeline和Vavle
  • StandardEngine类和StandardHost类
  • StandardContext类
  • 总结

Pipeline和Vavle

在第二节(How Tomcat works — 二、tomcat启动(1))中没有介绍关于Pipeline和Vavle,因为前面侧重的是整个架构,但是在初始化的时候就不得不说了。

Pipeline,就是一根管道,用来连接两个容器,在一个容器流向下一个容器的时候使用。在tomcat中也是这个意思,很形象,Engine、Host等都是容器,在执行完上一个容器(比如Engine)的相关操作的时候要开始执行下一个容器(比如Host)的操作了,这个时候需要经过一根管道pipeline,那么我们可以在管道中执行一个其他必要的操作,这个时候可以在管道上面添加Vavle(阀),一根管道pipeline上可以有多个阀门(也很形象)。每根管道都有一个默认的阀门。

在tomcat实现中有一个实现了Pipeline接口的类StandardPipeline——是每两个容器之间的管道,每个容器都有一个默认的Valve实现StandardEnginevavle、StandardHostValve、StandardContextVavle、StandardWrapperVavle。

其实valve的作用和filter的作用类似。

StandardEngine类

StandardEngine作为整个容器的最顶层负责启动其子组件——StandardHost,对,他就这一个作用。

StandardEngine.initInternal

这个方法被超类LifecycleBase.init方法调用,主要作用就是调用超类LifecycleMBeanBase.initInternal方法注册MBean,并初始化一个startStopExecutor(ThreadPoolExecutor),后面用来使用线程启动子容器。

StandardEngine.startInternal

这个方法的主要作用就是调用父类的方法Container.startInternal——主要的操作就在这个方法里面:

protected synchronized void startInternal() throws LifecycleException {// Start our subordinate components, if anyif ((loader != null) && (loader instanceof Lifecycle))((Lifecycle) loader).start();logger = null;getLogger();if ((manager != null) && (manager instanceof Lifecycle))((Lifecycle) manager).start();if ((cluster != null) && (cluster instanceof Lifecycle))((Lifecycle) cluster).start();Realm realm = getRealmInternal();if ((realm != null) && (realm instanceof Lifecycle))((Lifecycle) realm).start();if ((resources != null) && (resources instanceof Lifecycle))((Lifecycle) resources).start();// Start our child containers, if anyContainer children[] = findChildren();List<Future<Void>> results = new ArrayList<Future<Void>>();for (int i = 0; i < children.length; i++) {results.add(startStopExecutor.submit(new StartChild(children[i])));}boolean fail = false;for (Future<Void> result : results) {try {result.get();} catch (Exception e) {log.error(sm.getString("containerBase.threadedStartFailed"), e);fail = true;}}if (fail) {throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"));}// Start the Valves in our pipeline (including the basic), if anyif (pipeline instanceof Lifecycle)((Lifecycle) pipeline).start();setState(LifecycleState.STARTING);// Start our thread
    threadStart();}
View Code
  • manager、cluster、realm、resource如果有的话全部启动(所以其实tomcat本身就是支持集群的)
  • 调用findChildren方法找到左右子容器——也就是所有的StandardHost(默认只有一个)
  • 对于每个子容器(StandardHost)使用线程启动,StartChild类实现了Callable接口,在call方法里面执行传入容器的start方法,将子容器启动作为一个task,然后使用ThreadPoolExecutor.submit提交task
  • 然后等待这些Future执行完(因为里面是各个子容器的初始化和启动工作,后面connector必须在容器准备好之后才能启动)
  • 启动pipeline(这里就是StandardPipeline),pipeline会启动所包含的所有vavle(这里就是只有StandardEngineValve)
  • setState会通知所有监听了StandardEngine事件的listener
  • threadStart,启动一个后台线程执行包含的所有阀门的backgroundProcess方法,并触发Lifecycle.PERIODIC_EVENT事件

StandardHost类

StandardHost的作用和StandardEngine类似,都是初始化启动子容器,不过这里是StandardContext。启动的方式也一样,所以就不再详述。

StandardContext类

这个类才是重中之重,解析web.xml、部署webapp都在这儿实现。在StandardHost中调用StandardContext.start方法,执行的是超类LifecycleBase.start方法,主要进行了如下操作

  • 调用init方法初始化StandardContext
  • 调用startInternal方法启动StandardContext

init

在该方法中主要进行了MBean的注册,再就是触发了Lifecycle.AFTER_INITEVENT事件,ContextConfig是StandardContext的listener,在发生该事件的时候执行ContextConfig.init方法,在该方法中主要是构造一个能解析web.xml的digester。

startInternal

由于LifecycleBase没有实现该方法,所以就是直接调用StandardContext.startInternal,在StandardContext.startInternal方法中主要进行了如下操作:

  • setResource:添加新的resource
  • 如果webappLoader为null则初始化
  • 初始化charset mapper
  • 设置webapp工作目录,比如%TOMCAT_HOME%/work//Catalina/localhost/_等
  • 触发Lifecycle.CONFIGURE_START_EVENT事件,ContextConfig监听了该事件,会进行解析web.xml
  • 启动所有的children(StandardWrapper,代表所有配置的servlet)
  • 初始化Standardmanager
  • 配置initParam
  • 配置启动filter、listener

总结

container部分终于启动完成了,不过还是有些部分略过了,比如StandardWrapper(这个还可以往深挖,不过也包含在StandardContext的启动过程中)初始化和webapp的发布。到现在发现,这些启动过程就是围绕生命周期的这几个方法展开:

  • start和init:LifecycleBase提供了默认实现
  • startInternal和initInternal:这两个方法每个类都是重载实现自己需要启动的东西

转载于:https://www.cnblogs.com/sunshine-2015/p/5746920.html

相关文章:

DataList分页

<% Page Language"C#" %> <% Import Namespace"System.Data" %> <% Import Namespace"System.Data.OleDb" %> <Script Language"C#" Runat"Server"> /* Create By 飞刀 http://www.aspcn.com 20…

【中文】Joomla1.7扩展介绍之Googlemaps Plugin

Googlemaps Plugin 插件分类&#xff1a;Maps 支持版本&#xff1a;1.5 /1.6 /1.7 关注程度&#xff1a;【最流行的】 所属类型&#xff1a;插件、多语种 可以在 Joomla 1.5.x (native), 1.6.x and 1.7.x. 的内容条目、模块或者组件中显示一个&#xff08;或多个&#xff09;…

一文读懂:GoogleNet的Inception从v1到v4的演变

来源 | 机器学习炼丹术GoogleNet和VGG是ImageNet挑战赛中的第一名和第二名。共同特点就是两个网络的层次都更深了。但是&#xff1a;VGG继承了LeNet和AlexNet的一些框架结构而GoogleNet则做了更大胆的尝试&#xff0c;虽然深度有22层&#xff0c;但是参数却是Alexnet的1/12.而V…

几何画板画一个五边形内部的方法

五边形属于多边形里面比较简单的&#xff0c;就是在四边形的基础上增加一条边而已&#xff0c;五边形在平面几何学上指所有由五条边围衬成及有五个角的多边形。完美五边形和正五边形都是五边形的一种特殊类型。几何画板作为专业绘图工具&#xff0c;可以轻松就画出五边形&#…

GDAL Data Model(转)

即描述一个GDAL data store能够包含的信息的类型。 Dataset 一个dataset &#xff08;即一个GDALDataset 对象&#xff09;是一组相关的raster bands和一些属于它们的公共信息的集合。尤其是dataset有一个适用于它所有bands的关于raster size的概念&#xff0c;它是用pixels 和…

实战:人脸识别实战项目(源码共享)

首先我想问个问题&#xff1a;现在什么工程师最值钱&#xff1f;毫无疑问&#xff0c;我想超 90% 的都会说&#xff1a;人工智能工程师。也难怪&#xff0c;随着近几年人工智能的发展&#xff0c;已经逐渐渗透到了各个领域&#xff0c;比如&#xff1a;医疗、教育、机械自动化、…

Calendar如何只显示“一、二、三...日”,不显示“星期”

秋水无恨 asp.net Calendar DayNameFormat Globalization DayNames http://www.csdn.net/develop/Read_Article.asp?id15715 Calendar的DayNameFormat&#xff0c;如FirstLetter &#xff0c;FirstTwoLetters &#xff0c;Full &#xff0c;Short 但是争对英文而言的&#xf…

gulp插件之browser-sync安装报错

2019独角兽企业重金招聘Python工程师标准>>> 最近做前端开发&#xff0c;一直用gulp来写一些自动化脚本。之前用的npm的镜像为edunpm&#xff0c;很简单&#xff0c;因为这个镜像非常的快。 但是不知道为什么browser-sync插件总是下载不成功。。。 后来用nrm切换到t…

TensorFlow、PyTorch之后,“国产”AI框架还有没有机会?

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;众所周知&#xff0c;在机器学习框架领域&#xff0c;PyTorch、TensorFlow已分别成为目前学界和业界使用最广泛的两大实力玩家&#xff0c;而紧随其后的Keras、MXNet等框架也由于其自身的独特性受到开发者的喜爱。 202…

结构成员访问的三种方法

结构成员访问的三种方法 #include "stdio.h"#include "string.h"#include <stdlib.h>main (){struct student{int num;char * name;int score;}stu;struct student *p&stu;stu.num1;(*p).name"tom";p->score78;printf("%d\n&q…

数据库字段命名及设计规范

1.设计原则 1) 标准化和规范化数据的标准化有助于消除数据库中的数据冗余。标准化有好几种形式&#xff0c;但 Third Normal Form&#xff08;3NF&#xff09;通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。简单来说&#xff0c;遵守3NF 标准的数据库的表设计原则是…

更改管理GPO的域控制器

1.GPO先被存储到扮演PDC模拟器操作主机角色的域控制器&#xff0c;然后再由它将其复制到其他域控制器&#xff0c;域成员计算机再通过域控制器来应用GPO.2.可通过DC选项与组策略两种方式来将管理GPO的域控制器从PDC模拟器操作主机更改为其他域控制器。转载于:https://blog.51ct…

怎样使元素可编辑

作者&#xff1a;http://lucky.myrice.comE-mail:amxh21cn.com 在IE5.5中&#xff0c;可以设定元素的编辑属性。语法如下&#xff1a; object.contentEditable [ sEditable]; 其中的sEditable为下列三个之一&#xff1a; ◇inherit ◇false ◇true <script lang…

知乎多场景内容匹配方案荣获CSDN AI优秀案例奖

7月3日&#xff0c;由CSDN主办的2020 AI开发者大会拉开帷幕&#xff0c;以直播形式进行吸引了上万名技术从业者参与。大会颁发了2020 AI企业及技术应用系列奖项&#xff0c;其中知乎凭借“多场景内容匹配方案”荣获“AI优秀案例奖”。 过去一年&#xff0c;人工智能技术研发和…

批量创建用户和设置密码

(1) 首先创建用户名文件和密码文件 # touch user_name passwd active:/srv # cat passwd win00:123456 win01:123456 active:/srv # cat user_name win00:x:520:520::/home/win00:/bin/bash win01:x:521:521::/home/win01:/bin/bash (2) 然后执行命令导入用户名和密码 a…

Eclipse 小插件

http://www.junginger.biz/eclipse/

肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁

图源 | 视觉中国来源|Python编程时光&#xff08;ID: Cool-Python&#xff09;今天要给大家介绍的一个 Unix 下的一个 网络数据采集分析工具 -- Tcpdump&#xff0c;也就是我们常说的抓包工具。与它功能类似的工具有 wireshark &#xff0c;不同的是&#xff0c;wireshark 有图…

【中文】Joomla1.7扩展介绍之Fabrik (强大的表单处理能力)

Fabrik 插件分类&#xff1a; Contacts & Feedback > Forms 支持版本&#xff1a;1.5 /1.7 关注程度&#xff1a;【最流行的】 所属类型&#xff1a;组件、模块、插件、多语言 Fabrik 2.1.1 is a security fix, please update immediately Fabrik 2.1.1是一个安全…

CPU的序列号

可以取CPU的序列号。 string cpuInfo "";//cpu序列号 ManagementClass cimobject new ManagementClass("Win32_Processor"); ManagementObjectCollection moc cimobject.GetInstances(); foreach(ManagementObject mo in moc) { cpuInfo mo.Properties…

Sqli-labs less 9

Less-9 本关我们从标题就可以看到 《基于时间-单引号》&#xff0c;所以很明显的这关要我们利用延时注入进行&#xff0c;同时id参数进行的是 的处理。这里我们大致的将延时注入的方法演示一次。 这里用sleep()函数。 这里因为我们利用的是时间的延迟&#xff0c;贴图就没有意…

用ASP.NET上传图片并生成带版权信息的缩略图

作者&#xff1a;活靶子 出处&#xff1a;AspxBoy.Com <% Page Language"C#" ResponseEncoding"gb2312" %><% import Namespace"System" %><% import Namespace"System.IO" %><% import Namespace"Sys…

服务器ping你可以ping通,你ping服务器ping不同的解决方案!!

这几天让公司的服务器弄的蛋疼啊&#xff01;&#xff01;三天两头的出问题&#xff0c;主管脸色不大好看&#xff0c;我这里也郁闷的要死。所以发誓一定要把好安全关&#xff01;&#xff01; 今天在自己的虚拟机上边装了一个winserver2003标准版&#xff0c;搭建好环境之后发…

重磅!CSDN 发布「AI开源贡献奖Top5」「AI新锐公司奖Top10」「AI优秀案例奖Top30」三大榜单...

2020 年无疑是特殊的一年&#xff0c;AI 在开年的这场“战疫”中表现出惊人的力量。站在“新十年”的起点上&#xff0c;CSDN发起【百万人学AI】评选活动。我们继续聚焦AI的技术落地&#xff0c;关注开源和新生的力量。作为CSDN第三届AI评选活动&#xff0c;本次活动受到数百家…

linux 模拟生成 CAN 设备

/*************************************************************************************** linux 模拟生成 CAN 设备* 说明&#xff1a;* 最近在看CANopenSocket的过程中看到能够生成模拟的CAN设备&#xff0c;于是查了点资料&#xff0c;结…

关于委托的精彩解说

作者&#xff1a;TomMax (笑望人生) 出处&#xff1a;csdn community 主 题&#xff1a; “.net百题问答的活动”--许多人问过的--《 C#委托及事件 》作 者&#xff1a; TomMax (笑望人生) 信 誉 值&#xff1a; 100 所属论坛&#xff1a; .NET技术 C# 问题点数&am…

[转载]ESFramework 4.0 快速上手(15) -- 客户端登录验证

ESFramework 4.0 快速上手&#xff08;15&#xff09; &#xff0d;&#xff0d; 客户端登录验证 在之前版本的Rapid引擎中&#xff0c;是没有提供客户端登陆验证的机制的&#xff0c;如果要验证用户的帐号密码信息&#xff0c;我们只有自己手动通过自定义信息来实现。在2011.…

编程能力差,90%输在了这点上!CTO:这样学编程 ,更容易成为高手

从事 Python 这些年中&#xff0c;我见过很多 Python 教程和书籍&#xff0c;他们大都这样讲 &#xff1a;先介绍 Python 的基本语法规则、list, dict, tuple 等数据结构&#xff0c;然后再介绍字符串处理和正则表达式&#xff0c;介绍文件等 IO 操作.... 就这样一点一点往下说…

MVC 之 架构的基本原理及Asp.Net实现MVC

一、引言 许多Web应用都是从数据存储中检索数据并将其显示给用户。在用户更改数据之后&#xff0c;系统再将更新内容存储到数据存储中。因为关键的信息流发生在数据存储和用户界面之间&#xff0c;所以很多应用将数据和用户界面这两部分绑在一起&#xff0c;以减少编码量并提高…

vsftp虚拟用户

虚拟用户 1、建立虚拟用户口令库文件 #cat logins.txt mike 123 john 321 口令库文件中奇数行设置用户名&#xff0c;偶数行设置口令 2、生成vsftpd的认证文件 #rpm -ivh db4-utils* #db_load -T -t hash -f /root/logins.txt /etc/vsftpd/vsftpd_login.db 生成认证文件 设置…

在asp.net(C#)中怎么获得一个目录的大小?

作者&#xff1a;靶子&MSDN 出处&#xff1a;msdn 本方法来自以下文档,有问题多翻帮助 ;)ms-help://MS.NETFrameworkSDKv1.1.CHS/cpref/html/frlrfsystemiodirectoryclasstopic.htmms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemiodirectory…