从源码层面看spring boot tomcat启动流程

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管理.

在此就可以将整个流程串起来了。

写得比较跳,仅供自己看,梳理.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值