趁着假期 && 疫情, 沉澱一下設計模式
廢話很少說,直奔正題。學習
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
熱愛可抵歲月漫長,你們相互學習,謝謝。