导航菜单

深入分析SpringBoot源码如何内嵌Tomcat容器?

【一】总述

SpringBoot的诞生极大地简化了Spring框架的使用,提高了开发效率。它可以理解为集成包。使用SpringBoot,您可以通过一些简单的注释使用您自己的简单配置。可以构建基于REST的服务。同时,SpringBoot的快速构建和部署功能为当前热门的微服务登陆提供了极大的便利,可以说这是构建微服务的理想框架。

总之,SpringBoot具有以下功能:

自动配置内置的tomcat,jetty,下载三个Web容器以启动Web应用程序作为jar包

那么SpringBoot如何完成上述三个功能呢?这是我的下一个研究方向。本文重点介绍后两个特性。如何嵌入Web很容易,应用程序打包为jar包。它如何像Web应用程序一样运行?

本文是作者的好兄弟Dewey Ding和作者Debug几天的结果。我想纪念这篇文章。

【二】问题引出和总体思路

根据传统的Web容器启动方法,它显然与SpringBoot jar包的运行模式不兼容,那么它们如何无缝地协同工作呢?最后一次运行仍然是SpringMVC框架,那么SpringBoot如何在内置Tomcat时实现与SpringMVC的无缝集成?总之,需要在整个系列中研究的技术要点如下(本文未完全涵盖):SpringBoot启动TomcatSpringMVC初始化DispatcherServletTomcat两个启动方法如何在SpringBoot中获取配置

【三】SpringBoot启动过程具体分析

在SpringBoot中,Web应用程序从接收到接收请求开始,我大致将其分为四个步骤:

SpringBoot初始化SpringApplication:包括环境变量,资源,构造函数,启动监听器:启动监听器(listeners),加载配置(环境),创建上下文(applicationContext)自动化配置:这部分等到稍后再研究Tomcat初始化Tomcat接收请求SpringMVC初始化

这部分研究可以描述为曲折,每次调试

SpringBoot有一个main()方法,可以直接运行到jar包中; SpringMVC没有main方法,因此无法自行启动。为了依赖Tomcat,Tomcat本质上是一个容器,因此必须有一个main方法或一个线程的start()方法在Tomcat中启动。 Web应用程序需要Spring程序/WEB-INF。 SpringMVC将此配置为Tomcat进行读取,以便可以将Web容器项目部署到webapp目录以便由Tomcat运行。 SpringBoot没有这些配置。你如何做内置的Tomcat容器并让Tomcat启动?

【SpringBoot和Tomcat的初始化】

让我们先来看看Tomcat启动时Springcat启动的步骤。这里只是几个关键步骤:

SpringApplication的run方法刷新IOC容器(bean的实例化)在org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext中创建WebServer#onRefresh调用createWebServer这是Tomcat创建和启动过程,关于以下两行代码在中间,有一些我们尚未发现的秘密,我们将在稍后继续分析它们。 (它中包含的秘密真的伤害了我们,我们通过了它们,然后我们回到了一个大圈子,泪流满面~~):创建了Tomcat,Connector,Host,Engine并在这里设置了一些属性。至于Tomcat的具体内容,由于内容较多,本文不再详述,将在后面详细研究。在这里我们发现当Tomcat启动时,servletClass尚未获得dispatcherServlet,并且servletClass在第一次收到请求时成为dispatcherServlet。这对我们来说是一个误导性的原因,认为这是我们第一次收到它。 Tomcat仅在请求时加载了默认包装器,后来发现存在偏差。经过无数个断点后,它返回正确的路径。463e5cd8b77842a2bb9c34bdc235ba61将打印“Initializing Servlet'disadtcherServlet'”日志,org.springframework.web.servlet.FrameworkServlet #initWebApplicationContext这部分更重要,附上代码:

【四】SpringMVC和SpringBoot在启动过程中不同点归纳

关于SpringMVC,SpringBoot和Tomcat之间的合作,不同的起点总结如下:

SpringMVC首先启动tomcat,tomcat将转到web.xml,找到DispatcherServlet的上下文来初始化DispatcherServlet,从ServletContext中找到根上下文,然后在启动过程中没有办法创建root上下文Springboot,SpringBoot将给出DispatcherServlet Tomcat的Service的defaultWrapper(以后如何提供)当Tomcat启动时,它将匹配DispatcherServlet的“/”路径。启动第一个Web请求时,将初始化DispatcherServlet,包括HandlerMapping,HandlerAdapter。