美文网首页
7.3 Container 分析

7.3 Container 分析

作者: AssassinFGO | 来源:发表于2017-04-19 13:32 被阅读0次

7.3.1 ContainerBase的结构

Container 是 Tomcat 中容器的接口,其一共有四个子接口 Engine、Host、Context、Wrapper 一个默认实现类 ContainerBase,每个子接口都是一个容器,每个接口都有一个对应的 StandardXXX 实现类,并且都继承自 ContainerBase。同时 Container 还继承了 Lifecycle 借口,其和其子类都符合之前的生命周期管理模式。

Container 结构图

7.3.2 Container 的4个子容器

Container 的子容器是逐级包含的关系:

  • Engine:引擎,用于管理多个站点,一个Service 只能有一个 Engine。
  • Host:代表一个站点,也可以叫虚拟主机,通过配置 Host 就可以添加站点。
  • Context:代表一个应用程序,对应平时开发的一套程序,或者一个 WEB-INF 目录以及下面的 web.xml 文件。
  • Wrapper: 每个 Wrapper 封装一个 Servlet。


    Container 容器装配结构图

7.3.3 4种容器的配置方式‘

7.3.4 Container 的启动

Container 的启动通过 init 和 start 方法来完成,这两个方法会在 Tomcat 启动时被 Service 调用。Container 继承 Lifecycle 所以也是按照 Tomcat 的生命周期来管理,通过 init 和 start 进行初始化并调用子类的 initInternal 和 startInternal 方法进行具体处理,但是之前 Tomcat 整体结构的启动过程有所不同:

  • Container 的4个子容器有一个共同的父类 ContainerBase,这里定义了 Container 容器的 initInternal 和 startInternal 方法通用处理内容。
  • 除了最顶层容器的 init 是被 Service 调用的,子容器的 init 方法并不是在容器中逐层循环调用的,而是在执行 start 方法是时候通过状态判断还没有初始化才调用的(这是相对生命周期方法而言)。
  • start 方法除了在父容器的 startInternal 方法中调用,还会在父容器的添加子类的 addChild 方法中调用,这主要是因为 Context 和 Wrapper 是动态添加的,我们在站点目录下放一个应用的文件夹或者 war 包就可以添加一个 Context,在 web.xml 中配置一个 Servlet 就可以添加一个 Wrapper,所以 Context 和 Wrapper 都是在容器启动过程中才动态查找出来添加到相应的父容器中的

ContainerBase

containerBase 的** initInternal **方法主要是初始化 ThreadPollExecutor 类型的 startStopExecutor 属性,用于管理启动关闭的线程

initInternal 方法
containerBase 的 startInternal 方法主要做了5件事:
  • 如果有 Cluster 和 Realm 则调用其 start 方法;
  • 调用所有子容器的 start 方法启动子容器;
  • 调用管道的中 Valve 的 start 方法来启动管道;
  • 启动完成后将生命周期状态设置为 LifecycleState.STRATING 状态;
  • 启动后台线程定时处理一些事情。
startInternal 方法
  • Cluster 用于配置集群,作用是同步session。
  • Realm 是 Tomcat 的安全域,可以用来管理资源的访问权限。
  • 子容器使用 startStopExecutor 调用新线程来启动,可以提高效率。遍历future有两个作用:
    1. 其get方法是阻塞的,保证管道Pipeline 启动前容器就已经启动完成。
    2. 可以处理启动过程中遇到的异常。
  • 启动子容器的线程类型是 StartChild 是一个实现了Callable 的的内部类在 call 方法中调用注入子类的 start 方法。
  • 因为这里的 startInternal 是 ContainerBase 的方法,而所有的容器类都继承了 ContainerBase ,所以所有容器都会在启动过程中调用子类的 start 方法启动子容器

Engine

Service 会调用最顶层容器的 init 和 start 方法,如果使用了 Engine 就会调用 Engine 的生命周期方法

Engine 对应方法

Host

Host 的默认实现类 StandardHost 没有重写 initInternal 方法,所以会调用ContainerBase 的 initInternal 方法。重写了 startInternal 方法: startInternal 方法主要检查 Host 管道中是否有指定的 Valve(阀) ,如果没有则添加。

StandardHost startInternal 方法

Context

Context 的默认实现类 StandardContext 的 startInternal 方法会调用 web.xml 中定义的 Listener,另外还初始化了其中的 Filter 和 load-on-startup 的Servlet。

Standard Context startInternal 方法

Wrapper

StandardWrapper没有重写 initInternal 方法,重写了 startInternal 方法

  • 用 broadcaster 发送通知,主要用于 JMX;
  • 调用了父类 ContainerBase 的initInternal 方法;
  • 调用 setAvailable 方法让 Servlet 有效
Wrapper startInternal 方法

相关文章

网友评论

      本文标题:7.3 Container 分析

      本文链接:https://www.haomeiwen.com/subject/uigczttx.html