spring boot 启动tomcat流程,网上已经很多,这里只是给自己以后看,总结,不好勿喷,谢谢.
自动配置类流程:SpringBootApplication>>EnableAutoConfiguration>>
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors>>
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)>>
#invokeBeanDefinitionRegistryPostProcessors>>
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions>>
org.springframework.context.annotation.ConfigurationClassParser#parse(org.springframework.core.type.AnnotationMetadata, java.lang.String)>>
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports>>
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports>>
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process>>
#getAutoConfigurationEntry>>
#getCandidateConfigurations>>
#loadFactoryNames>>
#loadSpringFactories
启动流程总归以下三点:
1.spring 的生命周期中,留给后面开发的后门,这里并不是指后置处理器BeanPostProcessor
2.spring boot 中自动加载配置类,读取 META-INF/spring.factories 里面的配置类
3.SPI机制
一、读取并初始化依赖里面, META-INF/spring.factories 配置好的接口实现类,此时也利用spi机制
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//设置webapplicationType,这里后续会用到,WebApplicationType#SERVLET
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//这里加载META-INF/spring.factories,自动加载配置
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
二、在ServletWebServerApplicationContext类中,重写了onRefresh方法,添加了 createWebServer方法,用来启动tomcat,这里重点是这段代码行
ServletWebServerFactory factory = getWebServerFactory();
这里是获得启动容器类型,比如是tomccat,jetty,undertow,这里从debug来看TomcatServletWebServerFactory,但是它从哪里来呢?从前面的代码中看到,并没有实例此类,初步猜想应该是spring 容器里实现化了,先不管,继续向下看逻辑。
三、看到TomcatServletWebServerFactory中的getWebServer方法,就已经知道tomcat是如何创建的了
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
这就不需要解释了,就是设置tomcat参数,并启动,跟tomcat中间件是一套逻辑
四、回过头来,看看TomcatServletWebServerFactory是如何创建的,这里就是SPI机制作用了
这里根据经验,可以猜测应该是跟webServer有关的配置类,可以找到ServletWebServerFactoryAutoConfiguration, EmbeddedWebServerFactoryCustomizerAutoConfiguration 到底哪个呢?这里只能点进去看类的实现,终于发现是ServletWebServerFactoryAutoConfiguration中,ServletWebServerFactoryConfiguration.EmbeddedTomcat这个类
@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;
}
}
这里就是实现化然后交给spring管理.
在此就可以将整个流程串起来了。
写得比较跳,仅供自己看,梳理.