Spring Boot Tomcat启动原理源码分析

Spring Boot Tomcat启动原理源码分析

​ Spring Boot应用程序在启动时,执行ServletWebServerApplicationContext的onRefresh方法时,会从IOC容器中获取ServletWebServerFactory对象创建ServletWebServer。

​ ServletWebServerFactory是如何注册到Spring IOC中的,因spring-boot-autoconfigure中的spring.factories文件中配置了ServletWebServerFactoryAutoConfiguration,Spring Boot启动时会自动注册该配置类,该配置类中标注了ConditionalOnClass和ConditionalOnWebApplication注解,表示该应用程序是Servlet类型的应用时,该配置类才会被启用。EnableConfigurationProperties注解用于开启server配置属性自动装配。通过Import注解导入ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar(该类的作用在后续进行分析)和Spring Boot支持的Servlet容器配置类(EmbeddedTomcat、EmbeddedJetty、EmbeddedUndertow)。

@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)//需要Servlet才启用
@ConditionalOnWebApplication(type = Type.SERVLET)//需要Servlet才启用
@EnableConfigurationProperties(ServerProperties.class)//开启server属性自动装配
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {

    //代码略

}

EmbeddedTomcat源码分析

@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })//当前类路径存在Servlet、Tomcat、UpgradeProtocol类时,才会启用
	@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)//当前IOC容器中未配置ServletWebServerFactory时,才会启动
	static class EmbeddedTomcat {

        //配置TomcatServletWebServerFactory,用于创建tomcat
		@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;
		}

	}

TomcatServletWebServerFactory源码分析

public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory
		implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
	

    //创建tomcat
    //spring boot 启动时ServletWebServerApplicationContext执行onRefresh方法时,会调用该方法
	@Override
	public WebServer getWebServer(ServletContextInitializer... initializers) {
		if (this.disableMBeanRegistry) {
			Registry.disableRegistry();
		}
        //创建tomcat实例
		Tomcat tomcat = new Tomcat();
        //设置tomcat运行基础参数
		File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
		tomcat.setBaseDir(baseDir.getAbsolutePath());
        //创建connector
		Connector connector = new Connector(this.protocol);
		connector.setThrowOnFailure(true);
		tomcat.getService().addConnector(connector);
		customizeConnector(connector);
		tomcat.setConnector(connector);
		tomcat.getHost().setAutoDeploy(false);
        //配置tomcat engine
		configureEngine(tomcat.getEngine());
		for (Connector additionalConnector : this.additionalTomcatConnectors) {
			tomcat.getService().addConnector(additionalConnector);
		}
		prepareContext(tomcat.getHost(), initializers);
        //创建tomcat web server
		return getTomcatWebServer(tomcat);
	}
    
    省略部分代码...

}
	

在执行getTomcatWebServer方法时,TomcatServletWebServerFactory会创建TomcatWebServer对象

protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {   
    return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
}

创建TomcatWebServer对象时,在构造方法中会调用该类的initialize方法启动tomcat

	public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) {
		Assert.notNull(tomcat, "Tomcat Server must not be null");
		this.tomcat = tomcat;
		this.autoStart = autoStart;
		this.gracefulShutdown = (shutdown == Shutdown.GRACEFUL) ? new GracefulShutdown(tomcat) : null;
        //调用TomcatWebServer的初始化方法,启动tomcat
		initialize();
	}

	private void initialize() throws WebServerException {
		logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
		synchronized (this.monitor) {
			try {
				addInstanceIdToEngineName();

				Context context = findContext();
				context.addLifecycleListener((event) -> {
					if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
						// Remove service connectors so that protocol binding doesn't
						// happen when the service is started.
						removeServiceConnectors();
					}
				});

                // 启动tomcat
				// Start the server to trigger initialization listeners
				this.tomcat.start();

				// We can re-throw failure exception directly in the main thread
				rethrowDeferredStartupExceptions();

				try {
					ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
				}
				catch (NamingException ex) {
					// Naming is not enabled. Continue
				}

				// Unlike Jetty, all Tomcat threads are daemon threads. We create a
				// blocking non-daemon to stop immediate shutdown
				startDaemonAwaitThread();
			}
			catch (Exception ex) {
				stopSilently();
				destroySilently();
				throw new WebServerException("Unable to start embedded Tomcat", ex);
			}
		}
	}

在这里插入图片描述

ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar

执行invokeBeanFactoryPostProcessors方法时,会调用ConfigurationClassPostProcessor对象的方法对所有配置类进行解析,在解析过程中会读取ImportBeanDefinitionRegistrar的registerBeanDefinitions方法进行bean注册

public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {

		private ConfigurableListableBeanFactory beanFactory;

		@Override
		public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
			if (beanFactory instanceof ConfigurableListableBeanFactory) {
				this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
			}
		}

    	//在refresh方法中执行invokeBeanFactoryPostProcessors时调用
		@Override
		public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
				BeanDefinitionRegistry registry) {
			if (this.beanFactory == null) {
				return;
			}
            //注册WebServerFactoryCustomizerBeanPostProcessor
			registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor",
					WebServerFactoryCustomizerBeanPostProcessor.class);
            //注册ErrorPageRegistrarBeanPostProcessor
			registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor",
					ErrorPageRegistrarBeanPostProcessor.class);
		}

		private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class<?> beanClass) {
			if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
				RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
                //设置为true,在spring实例化bean时,会不执行beanPostProcessor的逻辑
				beanDefinition.setSynthetic(true);
				registry.registerBeanDefinition(name, beanDefinition);
			}
		}

	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值