推荐访问我的个人网站,排版更好看呦: 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的组件结构大概是这个样子的:
生命周期:Lifecycletomcat的启动过程非常规范,使用Lifecycle接口统一管理各组件的生命周期,根据各个组件之间的父子级关系,首先调用init()方法逐级初始化各组件,然后在调用start()的方法进行启动;
Lifecycle接口提供的方法如下,提供了init,start,destory等方法:
tomcat中的组件基本都继承了LifecycleMBeanBase类,LifecycleMBeanBase集成LifecycleBase,LifecycleBase实现Lifecycle接口:
LifecycleBase重写Lifecycle接口,比如init()方法,在init()方法中调用initInternal()方法,initInternal()方法是抽象方法,具体实现交由各个子类(组件)去实现。如果没有实现initInternal()方法,则调用默认的LifecycleMBeanBase的initInternal方法。
启动过程接下来从源码看一下tomcat的启动流程:
bootstraptomcat的入口类为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