tomcat8 源码分析 | 组件及启动过程

推荐访问我的个人网站,排版更好看呦: https://chenmingyu.top/tomcat-source-code/

tomcat 简介

​ Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,Tomcat服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器。

整体架构

首先我们先看一张图

在这里插入图片描述


看上图总结一下tomcat的组件主要包括:

server:整个servlet容器,一个tomcat对应一个server,一个server包含多个service

server在tomcat中的实现类是:StandardServer

service: 一个service包含多个connector(接受请求的协议),和一个container(容器)

多个connector共享一个container容器,

service在tomcat中的实现类是:StandardService

connector:链接器,负责处理客户端请求,解析不同协议及io方式

executor:线程池

container:包含engine,host,context,wrapper等组件

engine:servlet引擎,container容器中顶层的容器对象,一个engine可以包含多个host主机

engine在tomcat中的实现类是:StandardEngine

host:engine容器的子容器,一个host对应一个网络域名,一个host包含多个context

host在tomcat中的实现类是:StandardHost

context:host容器的子容器,表示一个web应用

context在tomcat中的实现类是:StandardContext

wrapper:tomcat中最小的容器单元,表示web应用中的servlet

wrapper在tomcat中的实现类是:StandardWrapper

所以tomcat的组件结构大概是这个样子的:

在这里插入图片描述

生命周期:Lifecycle

tomcat的启动过程非常规范,使用Lifecycle接口统一管理各组件的生命周期,根据各个组件之间的父子级关系,首先调用init()方法逐级初始化各组件,然后在调用start()的方法进行启动;

Lifecycle接口提供的方法如下,提供了init,start,destory等方法:

在这里插入图片描述

tomcat中的组件基本都继承了LifecycleMBeanBase类,LifecycleMBeanBase集成LifecycleBase,LifecycleBase实现Lifecycle接口:

在这里插入图片描述

LifecycleBase重写Lifecycle接口,比如init()方法,在init()方法中调用initInternal()方法,initInternal()方法是抽象方法,具体实现交由各个子类(组件)去实现。如果没有实现initInternal()方法,则调用默认的LifecycleMBeanBase的initInternal方法。

启动过程

接下来从源码看一下tomcat的启动流程:

bootstrap

tomcat的入口类为BootStrap的main方法

Bootstrap中main()方法如下,不重要的代码省略了

/** * Main method and entry point when starting Tomcat via the provided * scripts. * * @param args Command line arguments to be processed */ public static void main(String args[]) { ..... //初始化 bootstrap.init(); ..... if (command.equals("startd")) { args[args.length - 1] = "start"; //实例化各组件 调用Catalina类的load方法 daemon.load(args); //启动各组件 调用Catalina类的start方法 daemon.start(); } ..... }

bootstrap.init()的工作是初始化Bootstrap类,包含初始化类加载器

/** * Initialize daemon. * @throws Exception Fatal initialization error */ public void init() throws Exception { //初始化类加载 initClassLoaders(); ...... //实例化Catalina类 Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.getConstructor().newInstance(); ...... catalinaDaemon = startupInstance; } Catalina

接着调用刚初始化的Catalina类的实例catalinaDaemon的load()方法,重要的就两点

/** * Start a new server instance. */ public void load() { ..... // Digester... 实例化组件 Digester digester = createStartDigester(); .....加载server.xml...... file = configFile(); inputStream = new FileInputStream(file); inputSource = new InputSource(file.toURI().toURL().toString()); ...... // 初始化sever getServer().init(); } Digester

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxyfj.html