一般咱们都是在main方法中调用SpringApplication.run()方法启动SpringBoot应用的,web
今天来看一下启动过程当中都干了些什么。上图。spring
大体分为两步,第一步new一个SpringApplication对象,第二步调用其run方法。ide
在建立SpringApplication对象的时候作了如下几件事情:ui
(1)判断应用是否是Web应用,判断的依据是classpath中有没有Servlet和ConfigurableWebApplicationContext,具体来说就是,能不能成功获取到它们的Class对象spa
(2)设置Initializer和Listener3d
(3)判断main方法对象
这里有必要了解一下ApplicationContextInitializer和ApplicationListener是干什么的blog
首先,ApplicationContextInitializer它是初始化Spring ConfigurableApplicationContext的时候的回调接口,它会先于ConfigurableApplicationContext的refresh()方法被调用。而咱们知道ConfigurableApplicationContext的refresh()方法是在AbstractApplicationContext中实现的。接口
ApplicationListener是一个基于标准的EventListener的事件监听器,用的是观察者模式。事件
这两步都有一个共同点就是都调用getSpringFactoriesInstances()方法,下面看下:
它的做用就是从classpath中全部的META-INF/spring.factories文件中找到指定Key的值。(注意:是全部的META-INF/spring.factories)
而后将其以List形式返回,并实例化它们。
在咱们的例子中,这两次找的key值分别是:org.springframework.context.ApplicationContextInitializer和org.springframework.context.ApplicationListener
咱们具体看一下它们的值是什么
总之呢,咱们能够知道在容器启动的过程当中,ApplicationContextInitializer的initialize()方法在AbstractApplicationContext的refresh()方法以前被调用。
到此为止,SpringApplication对象已经建立好了,接下来调用其run()方法。
这里先来了解一下SpringApplicationRunListener,它是SpringApplication#run()方法的一个监听器,并无什么实质性的做用。
接下来在看run方法的时候,咱们将忽略SpringApplicationRunListener这个监听器。
第1步、建立一个ApplicationArguments对象,它是对咱们运行时传进来的参数的一个封装
第2步、建立并配置Environment。这里,若是是web环境,则建立StandardServletEnvironment,不然建立一个StandardEnvironment
第3步、打印Banner
第4步、初始化ApplicationContext。这里,若是是web环境,则实例化AnnotationConfigEmbeddedWebApplicationContext,不然实例化AnnotationConfigApplicationContext。
第5步、建立FailureAnalyzers对象
第6步、准备上下文
(1)若是BeanNameGenerator不为空,将其注册到BeanFactory。(PS:其实就是ApplicationContext)
(2)调用全部ApplicationContextInitializer的initialize()方法
(3)将ApplicationArguments和Banner的实例注册到Context
(4)加载Sources
到这里,sources中全部的Bean都被加载到Context中了
第7步、刷新Context。这里它直接调用的AbstractApplicationContext的refresh()方法,前面的文章已经介绍过了,这里再也不赘述。
第8步、调用Context中全部的ApplicationRunner和CommandLineRunner
到此为止,启动完成!!!
总结:
第1步、全部的源对象(source)保存到Set<Object> sources成员变量中
第2步、判断是否web环境
第3步、设置Initializer和Listener
第4步、判断main方法
第5步、建立ApplicationArguments对象
第6步、建立并配置环境
第7步、建立Banner
第8步、建立ApplicationContext
第9步、配置ApplicationContext。在这一步中会回调全部的ApplicationContextInitializer,还会注册一些特殊的Bean到Context,最重要的是会加载sources中所配置的全部的Bean到Context中。
第10步、刷新Context。这里直接调用AbstractApplicationContext的refresh()方法。
第11步、调用容器中全部的ApplicationRunner和CommandLineRunner