SpringBoot内置Tomcat启动原理
SpringBoot内置Tomcat启动原理
一、概述
当依赖spring-boot-starter-web
时,SpringBoot会通过ServletWebServerFactoryAutoConfiguration
进行服务器实例的自动配置。该自动配置类通过@Import
导入可用的Web容器工厂(默认为Tomcat),并通过IOC容器的refresh
过程创建并启动内置的Tomcat。
二、主要元素分析
1. ServletWebServerFactoryAutoConfiguration
自动配置类
**作用:**通过@Import
导入Tomcat,Jetty,Undertow等Web服务器配置。(只展示了关键代码)
@AutoConfiguration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({
ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class
})
public class ServletWebServerFactoryAutoConfiguration {
@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties,
ObjectProvider<WebListenerRegistrar> webListenerRegistrars,
ObjectProvider<CookieSameSiteSupplier> cookieSameSiteSuppliers) {
return new ServletWebServerFactoryCustomizer(serverProperties,
webListenerRegistrars.orderedStream().collect(Collectors.toList()),
cookieSameSiteSuppliers.orderedStream().collect(Collectors.toList()));
}
@Bean
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
ServerProperties serverProperties) {
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
}
}
2. ServletWebServerFactoryConfiguration
**重点:**通过内部类EmbeddedTomcat
配置Tomcat工厂。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
static class EmbeddedTomcat {
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.getTomcatConnectorCustomizers()
.addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatContextCustomizers()
.addAll(contextCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatProtocolHandlerCustomizers()
.addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));
return factory;
}
}
三、SpringBoot启动过程分析
1. 执行SpringApplication.run()
SpringBoot会根据当前环境,创建Spring容器,如AnnotationConfigServletWebServerApplicationContext
。
2. 调用容器的refresh()
refresh()
方法中的invokeBeanFactoryPostProcessors()
调用自动配置类,分析并创建服务器工厂Bean。
3. 调用onRefresh()
onRefresh()
添加实现,调用createWebServer()
创建Web服务器实例。
此方法流程:
**getWebServerFactory()**
:返回已配置的Tomcat工厂实例。- 创建Tomcat实例: 通过Tomcat工厂创建Tomcat实例。
- 启动Tomcat: 调用Tomcat实例的
start()
方法实现启动。 - 异步线程坐窗: 调用
startDaemonAwaitThread()
方法,坐窗等待请求。
refresh方法中的invokeBeanFactoryPostProcessors(beanFactory);方法来解析我们的自动配置类
然后会调用onRefresh方法(子类来实现)
调用这个方法的createWebServer
这个方法有一个getWebServerFactory方法
当然,这里获取到的是我们Tomcat的工厂
然后就去创建这个bean实例
最后返回给createWebServer方法
而这个方法中有一个getWebServer方法
调用子类的实现方法,负责启动Tomcat
首先new了一个tomcat实例,调用初始化方法去启动Tomcat
然后会执行startDaemonAwaitThread();方法进行挂起,等待请求
Tomcat启动后需要挂起(startDaemonAwaitThread()
),这是为了保持服务器的运行并持续接受客户端请求,如果主线程在启动后结束,整个进程会退出,导致服务器无法响应请求。通过挂起通过线程阻塞的方式让程序持续运行。
四 .如何将DispatcherServlet嵌入Tomcat中实现MVC集成
Spring MVC 的核心是 DispatcherServlet
,它负责将HTTP请求分发到相应的Controller进行处理。
Spring Boot 在启动过程中,通过 WebApplicationContext
自动将 DispatcherServlet
注册到内置的 Tomcat 中。
是 DispatcherServlet
,它负责将HTTP请求分发到相应的Controller进行处理。
Spring Boot 在启动过程中,通过 WebApplicationContext
自动将 DispatcherServlet
注册到内置的 Tomcat 中。