Spring 源碼分析總結篇一: Spring IOC篇

一、前言

本文,是本人在閱讀源碼過程中的一些內容整理和總結。
全文僅代表個人理解和意見,故難免出現錯誤,如若發現,歡迎指正。十分謝謝。

本文所涉及的文章內容均在 : Spring源碼分析:全集整理


關於 :ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessor 的詳細分析,可以在 Spring源碼分析:全集整理 中找到對應的分析文章。

二、正文

2.1 Spring IOC 實現個人感覺最重要的兩個類

  • ConfigurationClassPostProcessor : 完成了類的掃描和配置了的解析

  • AutowiredAnnotationBeanPostProcessor : 完成了非 Property 的屬性的注入


  1. ConfigurationClassPostProcessorBeanFactoryPostProcessor子類。

    postProcessBeanDefinitionRegistry : 解析所有需要註冊的配置類
    postProcessBeanFactory :對Full類型進行代理增強,保證@Bean方法正確語意。

  2. AutowiredAnnotationBeanPostProcessorBeanPostProcessor 子類,完成了@Autowired、@Value、@Inject註解的解析注入功能。也就是說 AutowiredAnnotationBeanPostProcessor 中才完成了屬性的注入。

2.2 Spring什麼時候掃描的包路徑?

Spring在啓動時候會將啓動類註冊到Spring容器中。在ConfigurationClassPostProcessor中,會將啓動類作爲配置類進行解析。由於啓動類上面有@ComponentScan註解,所以在ConfigurationClassParser# doProcessConfigurationClass中會解析這個註解, 根據解析後的路徑通過
his.componentScanParser, parse (componentScan,sourceClass.getMetadata () .getClassName())進行掃描,註冊掃描到的需要注入的類(被@Component 修飾的類)並進行注入,如果有配置類再進行遞歸的配置類解析。(掃描是在 方法 org.springframework.context. annotation.ClassPathBeanDefinitionScanner#doScan中進行的掃描,但是我偷懶了沒看具體實現)

2.2 ConfigurationClassPostProcessor 的解析流程

. ConfigurationClassPostProcessor完成了對各種配置類的掃描,並將其引入的bean註冊到BeanFactory中。

  1. postProcessBeanDefinitionRegistry方法邏輯(完成了各種配置類的解析和註冊)

  2. 獲取所有BeanFactory中的BeanDefinition

  3. 遍歷所有BeanDefinition,篩選出full或者lite 配置類,等待下一步處理。

    • Full 規則 :被 @Configuration 註解修飾 && proxyBeanMethods屬性爲true (默認爲true)
    • Lite規則:被@Component. @ComponentScan, @Import. @ImportResource修飾的類或者類中有被@Bean修飾的方法(該方法會被包裝成一個 BeanDefinition)
  4. 遍歷所有full 和lite配置類,解析各種註解,對配置類進行進一步的解析(因爲Lite的配置類需要二次解析,所以這裏主要是二次解析)

    • @Component進行解析:即如果當前配置類被@Component註解修飾,則去解析其內部類(包括靜態內部類和非靜態內部類)是否是配置類,如果是,遞歸解析發現的配置類。
    • :對@PropertySource進行解析:解析出其指定的配置文件內容,並保存到environment 中
    • :對@ComponentScan註解的解析:獲取註解指定路徑,進行掃描註冊。對新掃描出來的BeanDefinition進行判定是否是配置類,如果是,則遞歸去解析配置類
    • @Import、ImportSelector、ImportBeanDefinitionRegistrar的解析:因爲這三個註解或接口,本質上完成的功能是.一樣的,都是引入類。所以在這一部分的處理上只是區分了不同的類型
    • @ImportResource註解的解析:提取出@ImportResource註解的屬性,保存到configClassimportedResources屬性中
    • 對被@Bean修飾的方法的解析:提取出@Bean修飾的方法,保存的到configClassbeanMethods屬性中.
    • 對接口的默認方法解析:保存的到configClassbeanMethods屬性中
    • 對父類的解析:如果存在父類,則遞歸其父類進行解析。
  5. 遍歷所有的配置類,進行註冊

    • 處理引入的配置類:將配置類信息封裝成BeanDefinition,並註冊到BeanFactory
    • 處理@Bean修飾的方法將@Bean修飾的方法封裝成BeanDefinition,並註冊到BeanFactory
    • 處理@ImportResource註解引入的資源文件,獲取到BeanDefinition並註冊。
    • 處理@Import、ImportSelector、ImportBeanDefinitionRegistrar引入的類,註冊到BeanFactory中。

補充:4.1 中爲什麼要解析@Component?

  • 因爲過濾出來的配置類可能沒有被@Component修飾,比如僅僅是,可能是Spring硬編碼注入或者我們通過編碼注入的bean。如果沒有使用@Component註解修飾,就沒必要解析其內部類是否是配置類。比如最簡單的就是spring.factories文件中引入的類。可能滿足配置類判定,但並沒有被@Component修飾

2.3 AutowiredAnnotationBeanPostProcessor 的解析流程

AutowiredAnnotationBeanPostProcessor 完成@Autowired. @Value、 @Inject註解的功能, 完成了
Spring的注入

  1. determineCandidateConstructors 方法 :篩選出當前bean中能作爲構造注入的構造函數列表。用於構造注入

    • 處理了@Lookup註解,將@Lookup註解標註的方法保存了起來。這一步和構造函數的篩選沒有任何關係
    • 挑選候選構造函數。簡單邏輯就是有註解修飾選註解修飾的構造函數,沒有的話使用默認無參構造函數沒有無參構造函數,再沒有返回null.
  2. postProcessProperties 方法 :篩選Bean中需要注入的屬性,進行屬性注入。用於設置注入和註解注入遍歷每個屬性,找到被注入註解修飾的屬性。保存到currElements中。遍歷每個方法,找到被注入註解修飾的方法, 保存到currElements中。隨後遍歷currElements, 通過resolveDependency方法將方法或者屬性注入(resolveDependency方法是在populateBean方法中按照類型注入時調用的方法)這裏可以知道,按照順序遍歷,方法的屬性在屬性的後面,自動注入時,方法的注入結果會把註解屬性的注入覆蓋掉。

注: Spring注入的方式分爲三種 :構造注入、設值注入、註解注入。在AutowiredAnnotationBeanPostProcessor 中處理的實際是設置注入和註解注入。

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