1. 程式人生 > >SpringBoot原始碼之SpringApplication.run啟動流程

SpringBoot原始碼之SpringApplication.run啟動流程

  • SpringApplication初始化

設定初始化器列表:多個classpath*:META-INF/spring.factories中的屬性KEY為                        org.springframework.context.ApplicationContextInitializer的屬性的值。

         設定監聽器列表:多個classpath*:META-INF/spring.factories中的屬性KEY為                        org.springframework.context.ApplicationListener的屬性的值。

                

  • 呼叫SpringApplication的run方法

1.建立SpringApplicationRunListeners,並呼叫starting()

2.準備Environment

  • 獲取或建立Environment,WEB專案返回StandardServletEnvironment
  • 配置Environment
  • 釋出ApplicationEnvironmentPreparedEvent事件

3.列印Banner

4建立應用上下文AnnotationConfigEmbeddedWebApplicationContext

AnnotationConfigEmbeddedWebApplicationContext:

接受註解類作為輸入-特別是@Configuration,@Component和依從JSR-330使用 {@code javax.inject}註解的類。允許逐個註冊類(指定類名作為配置位置)以及類路徑掃描(指定基本包作為配置位置)。對於多個{@[email protected]}類,後面的{@[email protected]}定義將覆蓋先前載入檔案中定義的定義。可以通過額外配置類來有意的覆蓋某些bean定義。

EmbeddedWebApplicationContext:

此上下文會通過搜尋一個{@link EmbeddedServletContainerFactory}bean,建立,例項化,執行一個{@link EmbeddedServletContainer}

此外,在上下文中定義的任何{@link Servlet}或{@link Filter}bean將自動註冊到嵌入的Servlet容器。在單個servlet bean的情況下,將使用'/'對映。如果找到多個servlet bean,那麼小寫bean名稱將被用作對映字首。任何一個名為“dispatcherServlet”的servlet都將被對映到'/'。過濾器bean將被對映到所有URL(‘/*’)。

對於更高階的配置,上下文可以替代定義實現{@link ServletContextInitializer}介面的bean。為了防止雙重註冊,使用{@link ServletContextInitializer}bean將禁用自動Servlet和Filter bean註冊。雖然這個上下文可以直接使用,大多數開發者應該考慮使用{@link AnnotationConfigEmbeddedWebApplicationContext} or {@link XmlEmbeddedWebApplicationContext} 。

GenericWebApplicationContext:

實現{@link org.springframework.web.context.ConfigurableWebApplicationContext},但不用於{@code web.xml}中的宣告性設定。相反,它是為程式設定而設計的。例如:構建巢狀上下文 或者 為了在WebApplicationInitializer中使用。

如果你想實現一個從配置檔案中讀取BEAN定義的WebApplicationContext ,考慮從AbstractRefreshableWebApplicationContext讀取BEAN定義,通過loadBeanDefinitions方法的一個實現 。

將資源路徑解釋為servlet上下文資源,即作為Web應用程式根下的路徑。絕對路徑,例如web應用程式根目錄之外的檔案,可以通過“file:”URL訪問,如AbstractApplicationContext所實現的。除了由{@link org.springframework.context.support.AbstractApplicationContext}檢測到的特殊bean之外,這個類在上下文中檢測ThemeSource bean,名為“themeSource”。

GenericApplicationContext:

通用的ApplicationContext實現,持有一個內部的DefaultListableBeanFactory例項而且不承擔特定的bean定義格式。實現{@link org.springframework.beans.factory.support.BeanDefinitionRegistry}介面,以便允許對它應用任何bean定義讀取器。典型的用法是通過{@link org.springframework.beans.factory.support.BeanDefinitionRegistry}介面註冊各種bean定義,然後呼叫{@link #refresh()} 來用應用程式上下文語義初始化這些bean。與為每個重新整理建立新的內部bean工廠例項的其他應用程式上下文實現相反,此上下文的內部bean工廠可以從一開始就可用,以便能夠在其上註冊bean定義。{@link #refresh()}只能呼叫一次。例如 : 

 * GenericApplicationContext ctx = new GenericApplicationContext();
 * XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
 * xmlReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
 * PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(ctx);
 * propReader.loadBeanDefinitions(new ClassPathResource("otherBeans.properties"));
 * ctx.refresh();
 *
 * MyBean myBean = (MyBean) ctx.getBean("myBean");

5.準備上下文,實際上是把MAIN方法啟動類的BEAN定義註冊到BEAN工廠的MAP中。

6.重新整理上下文

  • prepareRefresh   準備此上下文以進行重新整理。
  • obtainFreshBeanFactory  告訴子類重新整理內部bean工廠。
  • prepareBeanFactory準備此BEAN工廠以進行使用。會註冊BEAN environment 到 單例BEAN註冊器???
  • postProcessBeanFactory允許在上下文子類中對bean工廠進行後處理。新增BEAN後置處理器WebApplicationContextServletContextAwareProcessor,忽略依賴的ServletContextAware介面。
  • invokeBeanFactoryPostProcessors 工廠後置處理器在上下文中註冊為bean。invokeBeanDefinitionRegistryPostProcessors,發現候選的元件(即:啟動類路徑下的最終由@Component註解的類,注意,@Controller @Service  @Configuration註解中包含@Component註解),將其初始化為BeanDefinitionHolder,並將其BEAN定義註冊到BEAN工廠的beanDefinitionMap
  • 檢查任何其他配置類的掃描定義集,並在需要時遞迴解析

          處理@ComponentScan註解

          處理@Import註解  啟動類有掃描到AutoConfigurationPackages$Registrar, EnableAutoConfigurationImportSelector,

ParserStrategyUtils.invokeAwareMethods呼叫AwareMethods,即:此Registrar/ImportSelector實現的Aware介面的Aware方法。

新增了一個DeferredImportSelectorHolder,在後面呼叫。

          處理@ImportResource註解

          處理獨特的@Bean methods  

          處理介面的預設方法

          處理父CLASS

          處理延期的ImportSelectors即:從多個classpath*:META-INF/spring.factories中的屬性KEY為                        org.springframework.boot.autoconfigure.EnableAutoConfiguration的屬性的值。去重,排序,去除exclusions:即spring.autoconfigure.exclude的值,過濾,只引入JPA的情況下,會返回以下配置類:

org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration, 
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, 
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration, 
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration, 
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration, 
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration, 
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration, 
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration, 
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration, 
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration, 
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, 
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, 
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration, 
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration, 
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, 
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration, 
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, 
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, 
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, 
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration, 
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration, 
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration, 
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration, 
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration

然後,釋出AutoConfigurationImportEvent,解析以上配置類中的@Bean註解的方法為BeanMethod。

以上配置類本身解析為BeanDefinition註冊到BeanFactory,這的BeanMethod也解析為BeanDefinition註冊到BeanFactory,呼叫 ImportBeanDefinitionRegistrar的registerBeanDefinitions方法註冊BeanDefinition到BeanFactory

invokeBeanFactoryPostProcessors 新增ImportAwareBeanPostProcessor

5.註冊bean處理器,攔截bean建立。

註冊下列BEAN  :

ConfigurationPropertiesBindingPostProcessor
PersistenceAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor

ProxyTransactionManagementConfiguration中的@BEAN會執行????

EmbeddedServletContainerCustomizerBeanPostProcessor
ErrorPageRegistrarBeanPostProcessor
DataSourceInitializedPublisher
ProjectingArgumentResolverBeanPostProcessor

6.初始化此上下文的訊息源。

7.初始化此上下文的事件多播器。

8.在特定上下文子類中初始化其他特殊bean。建立內建的Servlet容器,初始化屬性源。

8.檢查listener BEAN,並註冊它們。

9.例項化所有剩餘的(非懶初始化)單例。

10.釋出相應事件。

11.callRunners  ApplicationRunner  CommandLineRunner

12.釋出事件 ApplicationReadyEvent