上一节说到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

How Tomcat works — 四、tomcat启动(3)相关推荐

  1. how tomcat works(第17章: 启动Tomcat)

    本章的关注重点是Tomcat如何使用org.apache.catalina.startup下面的Catalina类和Bootstrap类来启动的.Catalina类用来启动和停止一个服务器对象并且解析 ...

  2. How Tomcat Works(十一)

    本文接下来分析tomcat的类载入器,tomcat需要实现一个自定义的载入器,而不能使用系统类载入器 (1)限制serlvet访问当前运行的java虚拟机中环境变量CLASSPATH指明的路径下的所有 ...

  3. 《How Tomcat Works》读书笔记(二)

    <How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对ser ...

  4. 《How Tomcat Works》读书笔记(三)Connector

    为什么80%的码农都做不了架构师?>>>    3.1 StringManager 为啥要先讲StringManager呢? 话说tomcat算是一个大型项目了(最新的tomcat7 ...

  5. tomcat mysql 启动顺序_linux 上配置tomcat、mysql 开机启动

    1.tomcat 开机启动 方法一.修改系统文件 (已经尝试,可以) 1.修改/etc/rc.d/rc.local vi /etc/rc.d/rc.local 2.添加下面两行脚本,记住是两行,仅仅第 ...

  6. how tomcat works

    目标 深入剖析tomcat how tomcat works •Java Web 服务性能优化实践2014-11-04阅读225 •How Tomcat work之第十五章之Digester之sett ...

  7. How Tomcat Works(二十)

    要使用一个web应用程序,必须要将表示该应用程序的Context实例部署到一个host实例中.在tomcat中,context实例可以用war文件的形式来部署,也可以将整个web应用拷贝到Tomcat ...

  8. How Tomcat Works(十三)

    本文分析tomcat容器的安全管理,servlet技术支持通过配置部署描述器(web.xml文件)来对受限内容进行访问控制:servlet容器是通过一个名为验证器的阀来支持安全限制的,当servlet ...

  9. (四)Linux环境部署(Centos+Nginx+Tomcat+Mysql) - 安装Tomcat和JDK 以及 Nginx与Tomcat整合

    因为在网上发现系统性.严谨(特别是在安全方面)的Linux部署方面的参考文章很少,于是整理以下六篇Linux环境部署的系列性文章,其为本人在实践中,完整的搭建一个基于Linux系统上Centos+Ng ...

最新文章

  1. php文章付费阅读系统球料付费阅读系统
  2. runtime 关联对象objc_setAssociatedObject
  3. Android之异步消息处理机制Handler源码解析
  4. 读取xml文件基于xpath
  5. 领域模型架构 eShopOnWeb项目分析 上
  6. (计算机组成原理)第一章计算机系统概述-第一节:计算机发展历程
  7. c# mysql 中文,c#操作mysql中文乱码的解决方案_c#应用
  8. 人工智能TensorFlow工作笔记005---计算图的基本应用_认识计算图
  9. 《电路》邱关源 思维导图 第六章-储能元件
  10. Pintech品致钳形交直流电流探头的主要功能
  11. 编辑器、编译器以及IDE
  12. Unity3D中玻璃、金属材质制作
  13. AI弄潮!深圳第一高楼智能访客系统“刷脸”通行
  14. linux dns访问日志内容格式,谢烟客---------Linux之DNS请求流程及资源记录定义
  15. 2022 年中回顾|一文看懂预训练模型最新进展
  16. 编程规范 --- 可读性
  17. 冯诺依曼 图灵计算机结构,冯诺依曼与图灵
  18. uni微信小程序引入商圈快速积分插件
  19. leetcode 421. Maximum XOR of Two Numbers in an Array
  20. 运行tomcat7w.exe未安装指定的服务S

热门文章

  1. 33.搜索插件——autocomplete
  2. C++中关于流的概念
  3. 怎么让百度快速重新收录
  4. Mysql 小数点后最多保留两位数
  5. INTERVAL数据类型-007学习笔记
  6. ThinkPad -- Intel 无线网卡网络连接方法限制及无法用 Fn + F5 控制的问题
  7. 2021年中国工业互联网安全大赛核能行业赛道writeup之入门的黑客
  8. oracle rac对心跳要求_关于心跳网络引起的Oracle RAC的节点驱逐(不是实例驱逐)...
  9. btf-raft共识算法_了解Raft共识算法:学术文章摘要
  10. Oracle的基本操作(一:子查询与常用函数)