欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Tomcat源码(二):tomcat启动之前的初始化

程序员文章站 2024-01-30 11:42:28
当tomcat启动的时候 首先会加载 org.apache.ctalina.startup.BootStrap类。 使用eclipse或idea启动tomcat其实就是在启动这个类的main方法 根据类的初始化 首先会 加载static静态块 然后进入main方法。 启动的主要步骤可以围绕BootS ......

当tomcat启动的时候 首先会加载 org.apache.ctalina.startup.bootstrap类。 使用eclipse或idea启动tomcat其实就是在启动这个类的main方法 

根据类的初始化 首先会 加载static静态块 然后进入main方法。

 

启动的主要步骤可以围绕bootstrap划分为 static中的 准备 和main中的初始化(init)、加载 (load)、启动(statrt)

1、 static

Tomcat源码(二):tomcat启动之前的初始化

    static静态块中做的事情是获取tomcat 的安装目录和创建catalina工作目录 ,为tomcat 的启动做准备

 catalina: catalina目录 在/work 目录下 ,是tomcat 的工作目录 在tomcat启动的时候被创建 , 负责存放项目中被编译后jsp文件 ,jsp即servlet ,默认当请         求首先请求jsp时 ,会将 webapps目录下            的.jsp 编译成.class文件

 2、main

  Tomcat源码(二):tomcat启动之前的初始化

 

Tomcat源码(二):tomcat启动之前的初始化

 

  main方法主要是 init、laod、start  (daemon = bootstrap),当start 方法加载完毕 ,就标志着tomcat启动完成  下面看这三步做了哪些事情

  (1)init

    Tomcat源码(二):tomcat启动之前的初始化

      初始化类加载器classloader (classloader负责将 .class 加载到jvm方法区进行类的初始化) 这里classloader主要是加载catalina.class 

     catalina 类: 是真正用于 初始化、启动tomcat 的类, 当运行到 bootstrap的main中的laod、start方法时 , 会通过反射 动态的加载 catalina类 中的 load、start方法 ,

        这也是为 什么init  中会先 获取类加载器 ,目的是 通过classloader 实例化catalina对象 ,为load和start做准备

   这里具体加载catalina类的是catalinaclassloader ,重写了 java的applicationclassloader ,目的是为了打破 classloader双亲委派机制提高性能

  (2)laod :比较复杂 ,涉及server、service、connector、engin、可分为如下几步  注意:load过程中并且有对 host、wapper 进行初始化 

     Tomcat源码(二):tomcat启动之前的初始化

    a、bootstrap.load(args);  :通过反射调用catalina的load方法 ,然后catalina的load方法来通过degister解析器解析server.xml来创建一个server对象,然后在通过set方法为server设置属性 
  b、然后getserver().init(); 对server进行初始化
  c、在初始化时再调用standardserver的initinternal方法调用services[i].init();(service可能存在多个)对service进行初始化
   d、在初始化时再调用standardservice的initinternal方法中调用engine.init();对engine初始化
   e、在初始化时再调用standardengine的initinternal方法进行调用getrealm()对进行安全设置域和调用父类的initinternal创建启停的线程池;接着启动线程池,
   f、初始化connector ,然后调用connector 的initinternal方法 初始化coyoteadapter适配器 、然后调用protocolhandler.init();
    g、进行protocolhandler的初始化,由于是protocolhandler接口在运行时在子类abstractprotocol的init方法中
调用endpoint.init();对endpoint(链接器的监听器)进行初始化 ,初始化完成
    
    i、standardxxx即 具体的组件类,如server组件在实例化时 ,就会创建standardserver对象
    ii、load阶段 ,最终只加载到 connector组件
    iii、在初始化时为什么调用initinternal方法 ? 
    上个博客提到lifecycle接口管理着所有容器的运行周期(init、start、stop等),其中lifecyclebase抽象类实现了 lifecycle接口 init方法具体实现如下
     

Tomcat源码(二):tomcat启动之前的初始化

      然后又重新定义了initinternal()抽象方法 ,server、service、engine、connector 等 各自 间接或直接的实现了 lifecyclebase类并实现了 initlnernal()的方法 ,因此在他们进行初始化的时候会调                       用自己 的 initlnternal()实现  。lifecycle中的 start()、stop() 也是这么来做的

            Tomcat源码(二):tomcat启动之前的初始化

     下一篇:tomcat的启动过程...