TOMCAT源码调试入口是Bootstrap类的main方法,我的启动参数VM:

-Dcatalina.home=E:/Tomcat_Source_Code/apache-tomcat-8.0.53-src/catalina-home
-Dcatalina.base=E:/Tomcat_Source_Code/apache-tomcat-8.0.53-src/catalina-home
-Djava.endorsed.dirs=E:/Tomcat_Source_Code/apache-tomcat-8.0.53-src/catalina-home/endorsed
-Djava.io.tmpdir=E:/Tomcat_Source_Code/apache-tomcat-8.0.53-src/catalina-home/temp
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.util.logging.config.file=E:/Tomcat_Source_Code/apache-tomcat-8.0.53-src/catalina-home/conf/logging.properties

Bootstrap执行main方法之前,先来看下static静态代码块做了哪些:

从当前系统变量、VM参数中获取 catalina.home作为 Bootstrap的 catalinaHomeFile,从系统变量、VM参数中获取catalina.base作为Bootstrap的catalinaBaseFile , 一般catalina.home和catalina.base 都指向同一个目录

main方法作为Bootstrap的入口,做了以下几个操作:实例化一个Bootstrap,并且调用Bootstrap的init,将Bootstrap实例赋给daemon属性;Bootstrap实例分别调用setAwait(true)、load、start方法;

Bootstrap实例初始化

简单描述下Boostrap初始化完成工作: 初始化类加载器、实例化Catalina、反射调用Catalina实例setParentClassLoader、Bootstrap持有Catalina实例。

一.初始化类加载器

这是Tomcat8.0官网中对ClassLoader的描述 Tomcat ClassLoader官网 ,Common就是此处的commonLoader, 至于下面还有两个 catalinaLoader 以及sharedLoader,为什么在8.0的源码中还存在呢?历史遗留问题,在Tomcat6.0以前的版本,类加载器结构是这样的 Tomcat5.5官网 。 所以在Tomcat6.0后仍然保留catalinaLoader、sharedLoader,只不过会发现他们指向commonLoader而已。

创建commonLoader类加载器

CatalinaProperties类静态代码块按照一下顺序尝试加载properties文件:从环境变量中读取catalina.config 、 或者catalina-home/conf/catalina.properties、或包org/apache/catalina/startup下catalina.properties,读取key-value并且通过System.setProperty保存在内存中,默认catalina-home/conf/catalina.properties文件中common.loader内容如下

common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"

使用replace方法将${catalina.base}替换成之前系统变量、VM参数中读取的catalina.base,将${catalina.home}替换成读取到的catalina.home;

getPaths方法再讲上面拆分成字符数组,catalina.home/lib  、catalina.home/lib/*.jar ,因为catalina.home和catalina.base是一样的;

将上面得到路径实例化成Repository,仓库的意思,比如catalina.home/lib 就是RepositoryType.DIR目录类型仓库,catalina.home/lib/*.jar就是RepositoryType.GLOB全局类型仓库,

利用仓库实例化URLClassLoader,比如DIR目录类型的仓库,校验catalina.home/lib是否存在、是否可读、是不是目录,之后通过file://路径构件URL统一资源定位符;比如GLOB类型仓库,遍历

catalina.home/lib下所有jar,每一个jar文件构造一个URL,最后得到new URLClassLoader(URL[] urls).

总结commonLoader:就是加载catalina.home下lib包中所有jar文件,而catalinaLoader、sharedLoader在Tomca6.0就都指向commonLoader了!

二.Catalina实例化

setSecurityProtection方法给Catalina的package.definition以及package.access属性赋值,这两个包定义、包访问属性来自于catalina.home/conf/catalina.propreties

实例化完成之后,通过反射调用Catalina的setParentClassLoader方法,参数为sharedLoader,沿用了Tomcat6.0之前,但是Tomcat6之后取消了sharedLoader以及catalinaLoader, 都是CommonLoader.  接着让Bootstrap关联Catalina实例,放在Bootstrap实例daemon的catalinaDaemon属性里。

Bootstrap加载、启动

Bootstrap实例加载之前,会调用setAwait方法, 上面Boostrap实例daemon持有catalinaDaemon,这里通过反射调用catalinaDaemon的setAwait为true,目的是为了让Tomcat程序处于运行状态,接收HTTP请求,一旦设置为false,Tomcat容器只是启动运行一遍就停止,所以说这一步不得不设置标志位!

Bootstrap加载load

bootstrap实例daemon只是作为一个辅助启动类,load方法也是如此,通过反射调用catalinaDaemon的load方法。Catalina实例的load篇幅比较长,下一篇博文记录。

Bootstrap启动start

Bootstrap作为辅助类,可以说相当尽心尽力了,启动Tomcat也是通过反射交给Catalina实例的start方法来完成。

总结

Tomcat的加载配置文件、启动过程都不是在Bootstrap中完成,都是通过Bootstrap反射调用Catalina实例的load、start方法,来完成Tomcat容器的启动。

而我觉得Bootstrap到这一步最大的作用,在于实例化commonLoader,通过加载catalina.properties文件中的的common.loader;创建了一个CommonLoader,赋给Catalina作为parentClassLoader。

Tomcat8源码笔记(二)Bootstrap启动的更多相关文章

  1. Tomcat8源码笔记(七)组件启动Server Service Engine Host启动

    一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...

  2. Tomcat8源码笔记(三)Catalina加载过程

    之前介绍过 Catalina加载过程是Bootstrap的load调用的  Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...

  3. Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目

    以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...

  4. Tomcat8源码笔记(六)连接器Connector分析

    根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...

  5. Tomcat8源码笔记(五)组件Container分析

    Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的? 说到Contai ...

  6. Tomcat8源码笔记(四)Server和Service初始化

    上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...

  7. Tomcat8源码笔记(一)Lifecycle接口

    第一次阅读Tomcat8源码,就以Lifecycle作为笔记阅读的开篇吧,一千个读者就有一千个哈姆雷特,每个人都Tomcat的理解都不同,如果不记录一次Tomcat源码可能忘了就忘了. 断断DEBUG ...

  8. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

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

    tomcat 8 源码分析 ,本文主要讲解tomcat拥有哪些组件,容器,又是如何启动的 推荐访问我的个人网站,排版更好看呦: https://chenmingyu.top/tomcat-source ...

随机推荐

  1. java多线程系列6 synchronized 加强版 ReentrantLock

    ReentrantLock类是可重入.互斥.实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力.ReenreantLock类的常用方法有: Re ...

  2. 网页打印样式CSS

    相信大多数的前端工程师都是处理显示屏上面的设计,用到最多的计量单位就是px,但是有些时候,我们难免也会有打印的需求,比如一个电商平台的“物流配送打印单”,“打印订单”等等可能都是需要从网友上打印出来的 ...

  3. iOS 开发之 KVC - setValuesForKeysWithDictionary 解析

    从字典映射到一个对象,这是KVC中的一个方法所提供的,这个方法就是 setValuesForKeysWithDictionary:,非常好用,不需要你来一一的给对象赋值而直接从字典初始化即可,但用的不 ...

  4. qhfl-1 跨域

    CORS跨域请求 CORS即Cross Origin Resource Sharing 跨域资源共享,那么跨域请求还分为两种,一种叫简单请求,一种是复杂请求 简单请求 HTTP方法是下列方法之一 HE ...

  5. 《mysql必知必会》学习_第15章_20180806_欢

    第15章:联结表 P98 外键:外键为某个表的一列A,同时这一列包含另一个表的主键值B(B属于A,等于或者小于的关系) P99 select vend_name,prod_name,prod_pric ...

  6. 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment

    [源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...

  7. Android 网络交互之下载断点续传

    一.概述 1.概念 断点续传主要用于下载,本文也主要讲述下载时的断点续传的逻辑思路.顾名思义,断点续传就是下载从中断的地方继续下载,一般是因为暂停或者网络故障导致的下载中断,当恢复下载的时候可以从已经 ...

  8. 理解js中的函数调用和this

    概述 这是我看typescript的时候看引用资源看到的,原文在这里:Understanding JavaScript Function Invocation and "this" ...

  9. Swift5 语言指南(八) 控制流

    Swift提供了各种控制流程语句.这些包括while多次执行任务的循环; if,guard和switch基于特定条件执行不同代码分支的语句; 和语句,如break和continue对执行流在你的代码转 ...

  10. javascript 异步解析

    js 异步解析 一 .js单线程分析 我们都知道js的一大特点是单线程,也就是同一时间点,只能处理一件事,一句js代码.那为什么js要设计成单线程而不是多线程呢?这主要和js的用途有关,js作为浏览器 ...