文档章节

SpringBoot:深入探索内嵌tomcat启动流程

wiitht
 wiitht
发布于 2017/08/16 16:23
字数 408
阅读 258
收藏 0

1.SpringBoot启动过程中所涉及的类:

springApplication -> run
stopwatch
AnnotationConfigApplicationContext: register, refresh  ->
AbstractApplicationContext -> refresh
AnnotationConfigEmbeddedWebApplicationContext
XmlBeanDefinitionReader
RepositoryConfigurationDelegate 
ClassPathMapperScanner
ConfigurationClassPostProcessor
GenericScope
AutowiredAnnotationBeanPostProcessor
TomcatEmbeddedServletContainer
StandardService
StandardEngine
WebApplicationContext
ContextLoader
ServletRegistrationBean
FilterRegistrationBean
RequestMappingHandlerMapping
EndpointHandlerMapping
SimpleUrlHandlerMapping
RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver
arterDeprecationWarningAutoConfiguration
URLConfigurationSource
AnnotationMBeanExporter
DefaultLifecycleProcessor
DocumentationPluginsBootstrapper
ApiListingReferenceScanner
CachingOperationNameGenerator
TomcatEmbeddedServletContainer
Application

2.初步分析SpringBoot启动过程

先看看在SpringApplication.run方法做了什么:

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.started();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			listeners.finished(context, null);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, analyzers, ex);
			throw new IllegalStateException(ex);
		}
	}

其中refreshContext内部执行了refresh方法

protected void refresh(ApplicationContext applicationContext) {
		Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
		((AbstractApplicationContext) applicationContext).refresh();
	}

这个方法会刷新整个应用需要启动的东西,具体的在AbstractApplicationContext中refresh方法内部可以看到所有要启动加载的东西:

 public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if(this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

在这个过程中会加载相应的xml,启动注册要加载的bean,启动tomcat等等

tomcat启动的过程会异步启动一个守护监听的scoket线程,这个线程通过NIOChannel包装;当第一次收到请求的时候会初始化相关的scoketWrapper数据,并在调用的过程中将socket的数据以http协议的方式转化成HttpRequest对象,并且在过程中会通过wrapper找到相应的dispacthservelt然后调用filter, 具体的controller.

 

 

 

© 著作权归作者所有

共有 人打赏支持
wiitht
粉丝 3
博文 158
码字总数 113941
作品 0
深圳
架构师
私信 提问
【SpringBoot专题】快速体验

前言 在Spring 4推出来之前,我们的编码是存在一些问题,比如:大量的xml配置存在项目中,配置相当繁琐;整合第三方框架非常麻烦;开发效率和部署效率不高等问题。正是因为这些问题,Spring开...

张丰哲
08/05
0
0
SpringBoot | 第一章:第一个SpringBoot应用

SpringBoot | 第一章:第一个SpringBoot应用 springboot简单介绍 概述 随着动态语言的流行(Ruby、Groovy、Scala、Node.js),Java的开发显得格外的笨重:繁多的配置、低下的开发效率、复杂的...

oKong
07/15
0
0
Spring Boot入门资料整理

Spring Boot 初识 SpringBoot前世今生 本文主要讲述spring boot的由来,即其它诞生的背景,初衷,现状,及对未来的展望。 Spring Boot参考指南中文版--Chapter1.Spring Boot中文文档 本节提供...

小致dad
2017/11/07
0
0
SpringBoot|第一章:第一个SpringBoot 应用

springboot简单介绍 概述 随着动态语言的流行(Ruby、Groovy、Scala、Node.js),Java的开发显得格外的笨重:繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术集成难度大。 在上述...

Java架构解析
08/18
0
0
第一章:Spring Boot 解决了什么问题?

spring4推出前存在的问题: 1、大量的xml文件,配置相当繁琐 2、整合第三方框架的配置问题 3、低效的开发效率和部署效率等问题 Spring Boot是什么? Spring Boot 伴随spring4.0诞生 Spring B...

刘祖鹏
05/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sed, awk 练习

1. sed打印某行到某行之间的内容 2. sed 转换大小写 将单词首字母转化大写 将所有小写转化大写 3. sed 在某一行最后面添加一个数字 4. 删除某行到最后一行 解析: {:a;N;$!ba;d} :a : 是...

Fc丶
59分钟前
2
0
babel6升级到7,jest-babel报错:Requires Babel "^7.0.0-0", but was loaded with "6.26.3".

自从将前端环境更新到babel7,jest-babel之前是基于babel6的,执行时候就会报:Requires Babel "^7.0.0-0", but was loaded with "6.26.3". 很烦,因为连续帮好几台电脑修复这个问题,所以记...

曾建凯
今天
1
0
探索802.11ax

802.11ax承诺在真实条件下改善峰值性能和最差情况。 如何改善今天的Wi-Fi? 在决定如何改进当前版本以外的Wi-Fi时,802.11ac,IEEE和Wi-Fi联盟调查了Wi-Fi部署和行为,以确定更广泛使用的障碍...

linuxprobe16
今天
2
0
使用linux将64G的SDCARD格式化为FAT32

一、命令如下: sudo fdisk -lsudo mkfs.vfat /dev/sda -Isudo fdisk /dev/sda Welcome to fdisk (util-linux 2.29.2). Changes will remain in memory only, until you decide to wri......

mbzhong
今天
4
0
深入理解Plasma(四):Plasma Cash

这一系列文章将围绕以太坊的二层扩容框架,介绍其基本运行原理,具体操作细节,安全性讨论以及未来研究方向等。本篇文章主要介绍在 Plasma 框架下的项目 Plasma Cash。 深入理解Plasma(1):...

HiBlock
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部