SpringBoot源码-SpringBoot内嵌Tomcat原理
一、什么是Tomcat?
Tomcat介绍:
Tomcat容器是一个开源的、轻量级的Java Web应用服务器,主要用于运行Java Servlet、JavaServer Pages(JSP)和Java Expression Language(EL)技术。以下是关于Tomcat容器的详细解释:
核心功能:Tomcat作为Servlet容器,负责处理客户端的HTTP请求,并将这些请求转化为服务器端的Java代码执行,最终生成HTTP响应返回给客户端。同时,它还支持JSP技术,允许开发者创建动态Web内容。
特点:Tomcat具有轻量级、多线程处理、配置灵活等特点。它可以在较低的硬件配置上运行,且能够同时处理多个客户端请求,提高服务器的并发性能。此外,Tomcat的配置非常灵活,可以根据具体的应用需求进行调优。
用途:Tomcat广泛用于部署和运行Java Web应用程序,这些应用程序通常打包成WAR文件并部署在Tomcat中运行。
综上所述,Tomcat容器是Java Web开发中的重要工具,为开发者提供了稳定、高效的运行环境。
Tomcat的架构图:
Bootstrap中的main方法:
bootstrap.init(); // 初始化类加载器
bootstrap.load(); // 间接调用Catalina,创建对象树,然后调用生命周期的init方法初始化整个对象树
bootstrap.start(); // 间接调用Catalina的start方法,然后调用生命周期的start方法启动整个对象树
二、SpringBoot中详解
spring-boot-autoconfigure\2.2.2.RELEASE\spring-boot-autoconfigure-2.2.2.RELEASE.jar!\META-INF\spring.factories这个自动装配的文件和注入了这两个和容器相关的类:
第一个是EmbeddedWebServerFactoryCustomizerAutoConfiguration
在这个配置类里面就是根据我们的配置来内嵌对应的Web容器,比如Tomcat或者Jetty等。
第二个是:ServletWebServerFactoryAutoConfiguration
首先来看下在类的头部引入和一些核心的信息
重点我们需要看下EmbeddedTomcat这个内部类。
看到的核心其实是创建了一个TomcatServletWebServerFactory对象并注入到了Spring容器中。这块的内容非常重要,是我们后面串联的时候的一个切入点。
现在开始debug源码看下再什么时候完成的tomcat的创建以及启动流程。
SpringApplication的run(String… args)方法中:
// 刷新应用上下文 完成Spring容器的初始化
refreshContext(context);
继续refreshContext:
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
继续refresh(context);
/**
* Refresh the underlying {@link ApplicationContext}.
* @param applicationContext the application context to refresh
*/
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext) applicationContext).refresh();
}
跳转到ServletWebServerApplicationContext的refresh方法:
public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
stopAndReleaseWebServer();
throw ex;
}
}
AbstractApplicationContext的refresh()找到onRefresh():
跳转到ServletWebServerApplicationContext的onRefresh:
开始创建webServer:
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
createWebServer方法如下:
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory(); // 获取WebServer的工厂对象
this.webServer = factory.getWebServer(getSelfInitializer()); // 获取具体的WebServer
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
factory.getWebServer(getSelfInitializer()); // 获取具体的WebServer如下:
factory是TomcatServletWebServerFactory和上面对应上了
可以看到,从容器中获取的工厂对象其实就我们上面注入的对象,然后根据工厂对象获取到了一个TomcatWebServer实例,也就是Tomcat服务对象。关键点我们需要看下getWebServer方法的逻辑
然后继续进入到 getTomcatWebServer方法中。
进入构造方法查看
进入Tomcat初始化的方法initialize方法
进入start方法
到这儿后面的逻辑其实就是Tomcat自身启动的逻辑了。这就需要你的Tomcat基础了,到这SpringBoot启动是如何内嵌Tomcat容器的到这儿就结束了哦。