前言
開心一刻
朋友喜歡去按摩庄新,第一次推門進來的是一個學生美眉,感覺還不錯薯鼠;后來經常去,有時是護士械蹋,有時是空姐出皇,有時候是教師。昨天晚上推門進去的是一個女警察哗戈,長得賊好看郊艘,身材也很好,朋友嗷的一聲就撲上去了唯咬。然后他就被抓起來了纱注,罪名是:嫖娼、襲警胆胰、強奸未遂狞贱。
路漫漫其修遠兮,吾將上下而求索蜀涨!
github:https://github.com/youzhibing
碼云(gitee):https://gitee.com/youzhibing
前情回顧
springboot2.3源碼篇之SpringApplication的構造方法
主要做了兩件事:
1瞎嬉、推測應用類型
根據類路徑下是否存在指定類型的類來斷定應用類型;
應用類型有三種:NONE厚柳、SERVLET氧枣、REACTIVE,NONO表示普通的java應用别垮,SERVLET表示基于servlet 的web工程便监,REACTIVE表示 reactive web application(還沒去了解,囧...)
2碳想、獲取ApplicationContextInitializer烧董、ApplicationListener實例
查找類路徑下全部的META-INF/spring.factories的URL(spring.factories文件的路徑),并加載所有spring.factories中的內容(包括各種Initializer移袍、ApplicationListener解藻、AutoConfigure、Failure analyzers等)到SpringFactoriesLoader的cache中葡盗;
然后從緩存中獲取ApplicationContextInitializer螟左、ApplicationListener類型的類并進行實例化啡浊,然后將得到的實例化集合分別賦值給SpringApplication的initializers和listeners
springboot2.3源碼篇之run方法(一):SpringApplicationRunListener
主要做了兩件事:
1、準備好運行時監(jiān)聽器:EventPublishingRunListener胶背,并過濾出于與ApplicationStartingEvent匹配的監(jiān)聽器
2巷嚣、廣播ApplicationStartingEvent事件,觸發(fā)對應的事件監(jiān)聽器
LoggingApplicationListener
檢測正在使用的日志系統
BackgroundPreinitializer
另起一個后臺線程執(zhí)行耗時的初始化
springboot2.3源碼篇之run方法(二):prepareEnvironment方法
1钳吟、獲取或創(chuàng)建環(huán)境
根據SpringApplication構造方法中推斷出的應用類型創(chuàng)建對應的環(huán)境廷粒,一般而言是web環(huán)境:StandardServletEnvironment
2、廣播ApplicationEnvironmentPreparedEvent事件红且,觸發(fā)相應的監(jiān)聽器
ConfigFileApplicationListener
添加名叫random的RandomValuePropertySource到environment
添加名叫applicationConfig:[classpath:/application.yml]的OriginTrackedMapPropertySource到environment
LoggingApplicationListener
初始化日志系統
3坝茎、加載外部化配置的資源到environment
包括命令行參數、servletConfigInitParams暇番、servletContextInitParams嗤放、systemProperties、sytemEnvironment壁酬、random次酌、application.yml(.yaml/.xml/.properties)等
springboot2.3源碼篇之run方法(三):createApplicationContext方法
1、實例化應用上下文
應用類型有三種舆乔,對應的上下文也有三種岳服,NONE ->?AnnotationConfigApplicationContext,SERVLET ->?AnnotationConfigServletWebServerApplicationContext希俩,REACTIVE ->?AnnotationConfigReactiveWebServerApplicationContext吊宋;一般而言,創(chuàng)建的是AnnotationConfigServletWebServerApplicationContext斜纪。
2贫母、實例化AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner和DefaultListableBeanFactory
AnnotatedBeanDefinitionReader是注解bean定義讀取器盒刚,用于編程式注解bean的注冊腺劣;ClassPathBeanDefinitionScanner是類路徑bean定義掃描器,用于檢測類路徑上的bean候選者因块。
AnnotatedBeanDefinitionReade用來加載class類型的配置橘原,在它初始化的時候,會預先注冊一些BeanPostProcessor和BeanFactoryPostProcessor涡上,這些處理器會在接下來的spring初始化流程中被調用趾断。ClassPathBeanDefinitionScanner是一個掃描指定類路徑中注解Bean定義的掃描器,在它初始化的時候吩愧,會初始化一些需要被掃描的注解芋酌。
DefaultListableBeanFactory,也就是我們所說的beanFactory雁佳,用來注冊所有bean定義(bean definitions)脐帝,也可以用來作為單例bean工廠同云。
springboot2.3源碼篇之run方法(四):prepareContext方法
1又跛、將SpringApplication中的部分屬性應用到上下文中
SpringApplication中的environment初坠、initializers、listeners應用到spring上下文中
2吁讨、廣播ApplicationPreparedEvent事件疚顷,觸發(fā)對應的事件監(jiān)聽器
向context的beanFactoryPostProcessors中注冊了一個PropertySourceOrderingPostProcessor實例
向beanFactory中注冊了一個名叫springBootLoggingSystem的單例bean旱易,也就是我們的日志系統bean
3、加載資源
支持4種方式:Class腿堤、Resource阀坏、Package和CharSequence。
Class:注解形式的Bean定義笆檀;AnnotatedBeanDefinitionReader負責處理全释。
Resource:一般而言指的是xml bean配置文件,也就是我們在spring中常用的xml配置误债。說的簡單點就是:將xml的bean定義封裝成BeanDefinition并注冊到beanFactory的BeanDefinitionMap中;XmlBeanDefinitionReader負責處理妄迁。
Package:以掃包的方式掃描bean定義寝蹈; ClassPathBeanDefinitionScanner負責處理。
CharSequence:以先后順序進行匹配Class登淘、Resource或Package進行加載箫老,誰匹配上了就用誰的處理方式處理。
springboot鼓勵用java類實現java bean定義黔州,所以springboot應用中耍鬓,我們一般只需要關注Class方式、Package方式即可流妻。
context中主要是三個屬性增加了內容:beanFactory牲蜀、beanFactoryPostProcessors和applicationListeners
三個事件
ApplicationStartingEvent
在監(jiān)聽器注冊完、SpringApplication構造完后绅这,以及其他的任何處理之前被廣播涣达,觸發(fā)對應的事件監(jiān)聽器
ApplicationEnvironmentPreparedEvent
environment創(chuàng)建后,context創(chuàng)建之前被廣播证薇,觸發(fā)對應的事件監(jiān)聽器
ApplicationPreparedEvent
bean定義加載后度苔,上下文refresh之前被廣播,觸發(fā)對應的事件監(jiān)聽器
后續(xù)還會涉及到ApplicationReadyEvent浑度、ApplicationFailedEvent事件寇窑,后續(xù)再詳解
關于事件機制,可到此處查看更多詳情
三個核心
springboot的特性之一箩张,內容如下
23. SpringApplication
23.1. Startup Failure
23.2. Customizing the Banner
23.3. Customizing SpringApplication
23.4. Fluent Builder API
23.5. Application Events and Listeners
23.6. Web Environment
23.7. Accessing Application Arguments
23.8. Using the ApplicationRunner or CommandLineRunner
23.9. Application Exit
23.10. Admin Features
也是springboot中比較重要的特性之一甩骏,用于從java main方法引導和啟動Spring應用程序窗市。其實給我印象最深的還是從spring.factories加載一系列的類,包括Initializer横漏、ApplicationListener谨设、AutoConfigure、Failure analyzers等等缎浇,springboot的自動配置扎拣,從此時已經開始了,一系列的AutoConfigure都是從spring.factories獲取的素跺。
environment:StandardServletEnvironment
表示當前應用程序所處的環(huán)境二蓝,主要包括兩方面:profiles和properties;例如我們經常說的本地指厌、運測刊愚、預發(fā)布、生產環(huán)境踩验,就可以通過environment進行配置鸥诽,以及是否是web環(huán)境。
一般而言箕憾,我們的環(huán)境是StandardServletEnvironment牡借,標準的servlet環(huán)境,也就是我們經常說的web環(huán)境
ApplicationContext:AnnotationConfigServletWebServerApplicationContext
應用上下文袭异,用于為應用程序提供配置的中央接口钠龙,提供如下內容:
1、訪問應用程序組件的Bean工廠方法
2御铃、加載文件資源的能力
3碴里、發(fā)布事件到已注冊的事件監(jiān)聽器的能力
4、解析消息上真,支持國際化的能力
等等一系列的功能
AnnotationConfigServletWebServerApplicationContext是springboot對spring應用上下文的拓展咬腋,引入了一些springboot的內容。