栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot Tomcat启动原理源码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot Tomcat启动原理源码分析

文章目录
  • Spring Boot Tomcat启动原理源码分析
      • EmbeddedTomcat源码分析
      • TomcatServletWebServerFactory源码分析
      • ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar

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 connectorCustomizers,
				ObjectProvider contextCustomizers,
				ObjectProvider> 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);
			}
		}

	}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/884765.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号