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