Spring源碼 系列一:配置類的初始化過程

前言

趁着假期 && 疫情, 沉澱一下設計模式

廢話很少說,直奔正題。學習

Spring的核心,即IOC和AOP,本篇文章其實就是來分析下 Spring 的 IOC 容器,IOC又叫控制反轉,把對象以Bean的形式交給IOC去管理,由Spring去管理對象的生命週期,使得Bean與Bean之間的鬆耦合。ui

Spring的註解啓動類this

進入 AnnotationConfigApplicationContext()spa

這裏主要是三個大方法:設計

this():初始化Spring的相關組件

this.register(annotatedClasses):把咱們的配置類註冊到IOC

this.refresh():這是個很重要很重要很重的方法!!!重要的事說三遍,後面會細說
複製代碼

咱們先看 this()方法3d

初始化了一個讀取器reader 和 一個掃描器scanner。而後:code

調用靜態方法 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
往容器裏注入Spring自帶的註解相關的組件(一共是6個),以下:
複製代碼

this()方法大體就這樣,接下來咱們來看看 this.register(annotatedClasses)方法orm

能夠看出,咱們的配置類能夠傳入多個,而後循環註冊

繼續往下,進入registerBean()
複製代碼

能夠看出,它把咱們的配置類封裝成了 beanDefinitionHolder

繼續往下,進入BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
複製代碼

繼續往下,進入registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
複製代碼

果斷選擇 DefaultListableBeanFactory 
複製代碼

經過上下文斷點+分析,程序最後走的是這段方法,即成功把咱們的配置類加入到beanDefinitionMap和beanDefinitionNames中去
複製代碼

前方高能 refresh()方法cdn

一共是12個大方法:本文只作與IOC相關的介紹
複製代碼

咱們關鍵看 this.invokeBeanFactoryPostProcessors(beanFactory);
複製代碼

繼續往下:
複製代碼

看源碼看關鍵流程  繼續往下:
複製代碼

Spring前面循環了全部的 BeanDefinition (容器自帶的+本身定義的)
而後把自定義的配置類抽離出來,放入 Set<BeanDefinitionHolder> candidates中
而後調用 ConfigurationClassParser解析器去解析自定義的配置 candidates 
繼續往下:
複製代碼

顯然是進入這裏,不作過多解釋 
繼續往下:
複製代碼

判斷自定義的配置類 有沒有 加ComponentScans註解
若是有加 
繼續往下:
複製代碼

先是獲得路徑集合basePackages,而後根據excludeFilter進行過濾 
調用掃描器的doScan方法進行掃描
繼續往下:
複製代碼

咱們發現實際上是一直在進行循環遞歸處理,直到basePackages循環完
複製代碼
解析器解析完了以後,獲得一個被解析過的 Set<BeanDefinitionHolder> candidates
調用 this.reader.loadBeanDefinitions(configClasses); 把配置類中與之關聯的bean信息註冊到容器中去
繼續:
複製代碼

分爲了四塊
    1.import引入的配置類
    2.內部的包含bean註解的方法
    3.importedResources引入的配置
    4.Registrars引入的配置
    
下面就沒啥好看的了,一直在往容器裏put就完事
複製代碼

總結

Spring的代碼算是比較複雜的,引入了大量的組件,以及設計模式,層層嵌套。

固然對咱們的提高也是有幫助的,學源碼學思想。

下一篇是計劃出AOP的博客

後面有時間的話,儘可能出一些Spring組件的相關文章,以及本身實現一套IOC以及AOP

熱愛可抵歲月漫長,你們相互學習,謝謝。

相關文章
相關標籤/搜索