spring-boot-2.0.3不一樣系列之源碼篇 - 階段總結

前言

  開心一刻

    朋友喜歡去按摩,第一次推門進來的是一個學生美眉,感覺還不錯;後來經常去,有時是護士,有時是空姐,有時候是教師。昨天晚上推門進去的是一個女警察,長得賊好看,身材也很好,朋友嗷的一聲就撲上去了。然後他就被抓起來了,罪名是:嫖娼、襲警、強姦未遂。

  路漫漫其修遠兮,吾將上下而求索!

  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、準備好運行時監聽器:EventPublishingRunListener,並過濾出於與ApplicationStartingEvent匹配的監聽器

    2、廣播ApplicationStartingEvent事件,觸發對應的事件監聽器

      LoggingApplicationListener

        檢測正在使用的日誌系統

      BackgroundPreinitializer

        另起一個後臺線程執行耗時的初始化

springboot2.3源碼篇之run方法(二):prepareEnvironment方法

    1、獲取或創建環境

      根據SpringApplication構造方法中推斷出的應用類型創建對應的環境,一般而言是web環境:StandardServletEnvironment

    2、廣播ApplicationEnvironmentPreparedEvent事件,觸發相應的監聽器

      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;一般而言,創建的是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事件,觸發對應的事件監聽器

      向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

    在監聽器註冊完、SpringApplication構造完後,以及其他的任何處理之前被廣播,觸發對應的事件監聽器

  ApplicationEnvironmentPreparedEvent

    environment創建後,context創建之前被廣播,觸發對應的事件監聽器   ApplicationPreparedEvent

    bean定義加載後,上下文refresh之前被廣播,觸發對應的事件監聽器

  後續還會涉及到ApplicationReadyEvent、ApplicationFailedEvent事件,後續再詳解

  關於事件機制,可到此處查看更多詳情

三個核心

SpringApplication

    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

    表示當前應用程序所處的環境,主要包括兩方面:profiles和properties;例如我們經常說的本地、運測、預發佈、生產環境,就可以通過environment進行配置,以及是否是web環境。

    一般而言,我們的環境是StandardServletEnvironment,標準的servlet環境,也就是我們經常說的web環境

  ApplicationContext:AnnotationConfigServletWebServerApplicationContext

    應用上下文,用於爲應用程序提供配置的中央接口,提供如下內容:

      1、訪問應用程序組件的Bean工廠方法

      2、加載文件資源的能力

      3、發佈事件到已註冊的事件監聽器的能力

      4、解析消息,支持國際化的能力

      等等一系列的功能

    AnnotationConfigServletWebServerApplicationContext是springboot對spring應用上下文的拓展,引入了一些springboot的內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章