spring-boot-2.0.3不一樣系列之原始碼篇

solution發表於2021-09-09

前言

  開心一刻

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

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

  github:

  碼雲(gitee):

    主要做了兩件事:

    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

  

    主要做了兩件事:

    1、準備好執行時監聽器:EventPublishingRunListener,並過濾出於與ApplicationStartingEvent匹配的監聽器

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

      LoggingApplicationListener

        檢測正在使用的日誌系統

      BackgroundPreinitializer

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

  

    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)等

  

    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工廠。

  

    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

檢視更多詳情

    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的內容。

原文出處:https://www.cnblogs.com/youzhibing/p/9708082.html  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2459/viewspace-2817695/,如需轉載,請註明出處,否則將追究法律責任。

相關文章