从tomcat源码分析它的启动流程是如何初始化servlet的
创始人
2025-06-01 16:48:26
0

首先我们需要了解两个重要的知识点:一个是tomcat容器的总体结构, 一个是lifecycle接口

tomcat容器的结构示意图如下:

它是一种层层包裹的结构类型,最外层是Server

然后Service里面有三大组件: Connector(处理外部网络请求), Executor(线程池)和Engine(tomcat容器)

然后Engine又是层层包裹结构: 最外层Engine=>Host>Context=>Wrapper(Servlet)。当Tomcat启动的时候,这些组件也要跟着一起启动,并且当Tomcat关闭的时候,这些组件也要同时关闭,并且要进行必要的清理操作

Lifecycle接口是所有tomcat组件的最顶层的接口,负责管理所有组件的生命周期。

它是通过观察者模式和模板方法来实现的,具体后面会讲

Lifecycle接口的最大的作用:统一各个组件的状态,因为我们看到tomcat组件是嵌套关系,如果外层组件已经启动,而内层组件却启动失败,那么这种状态就是有问题的,我们需要一种有效的触发机制,保证:从父级到子级的整个链条都能准确传导,动作保持一致,也就是:

当Tomcat启动的时候,这些组件也要跟着一起启动,并且当Tomcat关闭的时候,这些组件也要同时关闭,并且要进行必要的清理操作

然后我们从tomcat源码开始分析它的启动过程:

tomcat的启动类是org.apache.catalina.startup.Bootstrap,

Bootstrap的main方法主要是完成catalina对象的初始化和启动。

 public void init() throws Exception {initClassLoaders();Thread.currentThread().setContextClassLoader(catalinaLoader);SecurityClassLoad.securityClassLoad(catalinaLoader);// Load our startup class and call its process() methodif (log.isDebugEnabled()) {log.debug("Loading startup class");}// 通过反射加载Catalina类并进行实例化Class startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");Object startupInstance = startupClass.getConstructor().newInstance();// Set the shared extensions class loaderif (log.isDebugEnabled()) {log.debug("Setting startup class properties");}String methodName = "setParentClassLoader";Class paramTypes[] = new Class[1];paramTypes[0] = Class.forName("java.lang.ClassLoader");Object paramValues[] = new Object[1];paramValues[0] = sharedLoader;Method method =startupInstance.getClass().getMethod(methodName, paramTypes);method.invoke(startupInstance, paramValues);// 完成catalina对象的初始化catalinaDaemon = startupInstance;}

 从init方法的代码段可以看到init方法完成了catalina对象的初始化,然后回到bootStrap的main方法: 这里就开始启动catalina了:

 

上面就是通过反射启动了catalina。

然后我们看看catalina启动start方法又干了什么:

org.apache.catalina.startup.Catalina 类名

 注意:getServer().start()方法就是获取tomcat server,并且将它启动。

然后下面就重点的重点了,前面提到Lifecycle是tomcat所有组件的最顶层接口,那么也就是说

tomcat组件中的:StandardServer, StandardService,ContainerBase,StandardEngine StandardContext 等组件全部都会实现Lifecycle接口,可以说Lifecycle是所有tomcat组件的大总管:管理了这些组件从初始化,创建,销毁的所有生命周期,以及对这些组件的监听、事件发布、消息传递以及状态的更新。

然后继续回到源码:

getServer方法返回的Server实际继承了Lifecycle接口,换句话说Server也是接口,

那么我们进去看看Server接口的实现类是什么?

 可以看到Server的唯一实现类是StandardServer

然后我们继续从上面的getServer().start()方法往下走,发现会跳到Lifecycle的start方法。

然后这个start方法的实现类是LifecycleBase 

注意了:LifecycleBase是Lifecycle的实现类,而且是一个抽象类,这是整个Tomcat组件中影响最重要的一个类,因为这里定义了通用的模板方法设计,而且会被组件反复调用

 然后我们看看LifecycleBase的start方法:

 这个里面最重要的方法是startInternal方法,然后点进去看看:

 然后startInternal方法又会跳回到Lifecycle接口,注意到startInternal方法是一个抽象方法,这是典型的模板方法设计模式,  也就是他的子类必须重写该方法,此时我们应该选择哪一个实现类呢?因为实现类下面有很多选项。前面的getServer已经提到上面执行的实际是StandardServer的start方法,所以这里应该选择StandardServer作为startInternal方法的实现类。

这里可以看到:startInternal方法会遍历service集合,然后执行service的start方法。

那么Service又是什么类型?

 Service是一个继承了Lifecycle的子接口,而StardardService是Service的唯一实现类

 

然后仍然回到上面StandardServer中startInternal方法中的 service的start方法。这里会跟前面一样:先进入到LifecycleBase的start方法,然后接着进入到LifecycleBase的start方法:

 LifecycleBase的start方法仍然重点看startInternal方法

 startInternal方法是实现类选择StandardService,因为上面方法的执行源头是service.start,而service实际就是StandardService.

 从上面可以看到:组件的start方法=》 Lifecycle的start方法=》LifecycleBase的start方法=》  实现类(组件)的 startInternal方法

这一段逻辑会反复被调用,这就是典型的模板方法设计。

然后进入StandardService的startInternal方法,这里我们重点看它做的两件事:

  1. 启动servlet容器(容器的最外层:Engine)

  2. 启动线程池

我们重点看看servlet容器部分,也就是engine,Engine是servlet的顶层容器

Engine是一个接口,它的继承关系如下:

Engine=> Container=>Lifecycle

而StandardEngine是Engine的唯一实现类,

 所以可以推断上面的engine.start方法必然还是和前面一样的套路:=》 Lifecycle的start方法=》LifecycleBase的start方法=》  StandardEngine的 startInternal方法

所以我们跳过这些重复的模板方法,直接进入StandardEngine的 startInternal方法:

 然后这里又会执行它父级ContainerBase的startInternal方法:

 这里重点看一下findChildren方法:

 

从这里我们可以推断findChildren是找到Engine底下所有的嵌套容器:包括Host,Context, Wrapper等,因为Children是一个HashMap,key是容器名,而它的value就是容器实例。

然后回到前面的代码段,继续跟着findChildren方法,可以发现:这里会遍历四层嵌套容器,并通过线程池启动他们的start方法

       // Start our child containers, if anyContainer children[] = findChildren();List> results = new ArrayList<>();for (Container child : children) {// 遍历四层嵌套容器,并通过线程池启动他们的start方法results.add(startStopExecutor.submit(new StartChild(child)));}

我们可以看到StartChild是一个Callable函数式接口的实现类,构造器参数就是Container实例,并重写了call方法,在该方法里面执行container容器的start方法。

 而从Container的层级关系可以看到:Container包括了Host,Context, Wrapper这些嵌套容器

所以上面的那个for循环最终也会启动Wrapper的start方法,Wrapper也就是Servlet容器

 而StardardWrapper就是Wrapper的实现类,从上图可以看到:它确实就是定义了一个servlet容器

但是Wrapper是由它父级容器Context启动的,所以从加载的因果关系来看:我们应该先看看Context的实现类StandardContext的start方法:

而它的start方法必然还是和前面一样的套路:=》 Lifecycle的start方法=》LifecycleBase的start方法=》  StandardContext的 startInternal方法

所以我们跳过这些重复的模板方法,直接进入StandardContext的 startInternal方法:

这个方法代码很长,我们重点进入下面代码段的loadOnStartup方法

进入到loadOnStartup方法后,最重要的方法来了: wrapper.load方法,这个方法就是加载servlet容器

 可以看到:上面的wrapper.load方法实际执行的是它的实现类StandardWrapper的load方法,最终我们定位到了初始化servlet的代码: initServlet

 而initServlet方法会调用servlet的init方法

至此tomcat源码从启动流程到跟踪servlet初始化的整个分析过程已经全部完成。

相关内容

热门资讯

美国不提安卓系统华为,迈向自主... 华为与美国:一场关于技术、市场与政策的较量在当今这个数字化的世界里,智能手机已经成为我们生活中不可或...
安卓系统怎么打开ppt,选择文... 你有没有遇到过这种情况:手里拿着安卓手机,突然需要打开一个PPT文件,却怎么也找不到方法?别急,今天...
谷歌退回到安卓系统,探索创新未... 你知道吗?最近科技圈可是炸开了锅,谷歌竟然宣布要退回到安卓系统!这可不是一个简单的决定,背后肯定有着...
安卓系统待机耗电多少,深度解析... 你有没有发现,手机电量总是不经用?尤其是安卓系统,有时候明明没怎么用,电量就“嗖”的一下子就下去了。...
小米主题安卓原生系统,安卓原生... 亲爱的手机控们,你是否曾为手机界面单调乏味而烦恼?想要给手机换换“衣服”,让它焕然一新?那就得聊聊小...
voyov1安卓系统,探索创新... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那个让手机焕发青春的Vivo V...
电脑刷安卓tv系统,轻松打造智... 你有没有想过,家里的安卓电视突然变得卡顿,反应迟钝,是不是时候给它来个“大保健”了?没错,今天就要来...
安卓系统即将要收费,未来手机应... 你知道吗?最近有个大消息在科技圈里炸开了锅,那就是安卓系统可能要开始收费了!这可不是开玩笑的,这可是...
雷凌车载安卓系统,智能出行新体... 你有没有发现,现在的汽车越来越智能了?这不,我最近就体验了一把雷凌车载安卓系统的魅力。它就像一个聪明...
怎样拍照好看安卓系统,轻松拍出... 拍照好看,安卓系统也能轻松搞定!在这个看脸的时代,拍照已经成为每个人生活中不可或缺的一部分。无论是记...
安卓车机系统音频,安卓车机系统... 你有没有发现,现在越来越多的汽车都开始搭载智能车机系统了?这不,咱们就来聊聊安卓车机系统在音频方面的...
老苹果手机安卓系统,兼容与创新... 你手里那台老苹果手机,是不是已经陪你走过了不少风风雨雨?现在,它竟然还能装上安卓系统?这可不是天方夜...
安卓系统7.dns,优化网络连... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,别急,让我来给你揭秘这可能与你的安卓系...
安卓手机系统怎么加速,安卓手机... 你有没有发现,你的安卓手机最近变得有点“慢吞吞”的?别急,别急,今天就来给你支几招,让你的安卓手机瞬...
小米note安卓7系统,探索性... 你有没有发现,手机更新换代的速度简直就像坐上了火箭呢?这不,小米Note这款手机,自从升级到了安卓7...
安卓和鸿蒙系统游戏,两大系统游... 你有没有发现,最近手机游戏界可是热闹非凡呢!安卓和鸿蒙系统两大巨头在游戏领域展开了一场激烈的较量。今...
安卓手机没有系统更,揭秘潜在风... 你有没有发现,现在安卓手机的品牌和型号真是五花八门,让人挑花了眼。不过,你知道吗?尽管市面上安卓手机...
充值宝带安卓系统,安卓系统下的... 你有没有发现,最近手机上的一款充值宝APP,在安卓系统上可是火得一塌糊涂呢!这不,今天就来给你好好扒...
安卓系统8.0镜像下载,轻松打... 你有没有想过,想要给你的安卓手机升级到最新的系统,却不知道从哪里下载那个神秘的安卓系统8.0镜像呢?...
安卓系统修改大全,全方位修改大... 你有没有想过,你的安卓手机其实是个大宝藏,里面藏着无数可以让你手机焕然一新的秘密?没错,今天就要来个...