侧边栏壁纸
博主头像
再见理想博主等级

只争朝夕,不负韶华

  • 累计撰写 112 篇文章
  • 累计创建 64 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Tomcat启动流程

再见理想
2022-05-27 / 0 评论 / 0 点赞 / 336 阅读 / 973 字

一,启动步骤

1.1 启动tomcat , 需要调用 bin/startup.bat (在linux 目录下 , 需要调用 bin/startup.sh), 在startup.bat 脚本中, 调用了catalina.bat。

1.2 在catalina.bat 脚本文件中,调用了BootStrap 中的main方法。

1.3 在BootStrap 的main 方法中调用了 init 方法 , 来创建Catalina 及 初始化类加载器。

1.4 在BootStrap 的main 方法中调用了 load 方法 , 在其中又调用了Catalina的load方法。

1.5 在Catalina 的load 方法中 , 需要进行一些初始化的工作, 并需要构造Digester 对象, 用于解析 XML。

1.6 然后在调用后续组件的初始化操作 。加载Tomcat的配置文件,初始化容器组件 ,监听对应的端口号, 准备接受客户端请求。

二,源码解析

2.1,Lifecycle

由于所有的组件均存在初始化、启动、停止等生命周期方法,拥有生命周期管理的特性, 所以Tomcat在设计的时候, 基于生命周期管理抽象成了一个接口 Lifecycle ,而组件 Server、Service、Container、Executor、Connector 组件 , 都实现了一个生命周期的接口,从而具有了以下生命周期中的核心方法:

package org.apache.catalina;

public interface Lifecycle {
    String BEFORE_INIT_EVENT = "before_init";
    String AFTER_INIT_EVENT = "after_init";
    String START_EVENT = "start";
    String BEFORE_START_EVENT = "before_start";
    String AFTER_START_EVENT = "after_start";
    String STOP_EVENT = "stop";
    String BEFORE_STOP_EVENT = "before_stop";
    String AFTER_STOP_EVENT = "after_stop";
    String AFTER_DESTROY_EVENT = "after_destroy";
    String BEFORE_DESTROY_EVENT = "before_destroy";
    String PERIODIC_EVENT = "periodic";
    String CONFIGURE_START_EVENT = "configure_start";
    String CONFIGURE_STOP_EVENT = "configure_stop";

    void addLifecycleListener(LifecycleListener var1);

    LifecycleListener[] findLifecycleListeners();

    void removeLifecycleListener(LifecycleListener var1);

    void init() throws LifecycleException;   //初始化组件

    void start() throws LifecycleException;  //启动组件

    void stop() throws LifecycleException;  //停止组件

    void destroy() throws LifecycleException;  //销毁组件

    LifecycleState getState();

    String getStateName();

    public interface SingleUse {
    }
}

从上面可以看出,Lifecycle 其实就定义了一些状态常量和几个方法,这里主要看 init、start、stop 三个方法,所有需要被生命周期管理的容器都要实现这个接口,并且各自被父容器的相应方法调用。例如,在初始化阶段,根容器 Server 组件会调用 init 方法,而在 init 方法里会调用它的子容器 Service 组件的 init 方法,以此类推。

Tomcat 内部架构中各个核心组件有包含与被包含的关系,例如,Server 包含 Service, Service 包含 Container 和 Connector,往下再一层层包含。Tomcat 就是以容器的方式来组织整个系统架构的,就像数据结构的树,树的根节点没有父节点,其他节点有且仅有一个父节点,每个父节点有零个或多个子节点。鉴于此,可以通过父容器启动它的子容器,这样只要启动根容器,即可把其他所有容器都启动,达到统一启动、停止、关闭的效果。

2.2,源码入口

org.apache.catalina.startup.Bootstrap#start

2.3,总结

从启动流程图中以及源码中,我们可以看出 Tomcat 的启动过程非常标准化, 统一按照生命周期管理接口 Lifecycle 的定义进行启动。首先调用 init() 方法进行组件的逐级初始化操作,然后再调用 start() 方法进行启动。每一级的组件除了完成自身的处理外,还要负责调用子组件响应的生命周期管理方法,组件与组件之间是松耦合的,因为我们可以很容易的通过配置文件进行修改和替换。

0

评论区