一般咱們都是在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