Spring原始碼重頭再學習(二) IOC(下)

2021-10-09 11:30:48 字數 2503 閱讀 6354

廢話不多說,直接進入正題

沒錯,就是ioc最重要的乙個過程,例項化bean

也就是finishbeanfactoryinitialization(beanfactory)這個方法

原始碼中的注釋是 instantiate all remaining (non-lazy-init) singletons.

翻譯一下就是 : 例項化所有剩餘的(非懶載入)單例,很好理解吧

好了,我們點進去,開始閱讀

為了方便大家閱讀,我把所有注釋都翻譯成了中文,如果英語比較好的同學, 建議看英文,畢竟翻過之後會少點意思。

這裡我們主要看最後乙個方法,例項化非懶載入的單例。

好了,進入這個方法之後

主要看getbean方法,其他我也用注釋寫了大家一看就知道了。這個方法一直跟進去,就到了dogetbean()方法

大家應該都知道,先是會去快取裡面找bean,如果沒有,才會建立bean

建立bean的過程,spring根據scope做了區分,單例,多例,自定義scope,而大多數情況都是單例,所以我們看這個**

該方法進去,繼續跟進docreatebean()方法,然後主要先看這個方法

這個方法主要是做通過反射拿到class物件,然後通過反射呼叫建構函式建立例項。值得一提的是,這裡區分了正在例項化的bean中有@autowird註解的建構函式的情況。那麼大家可以想一想,如果建構函式上有@autowird,你會怎麼做?其實不難想明白,我相信大多數人想的,和spring原始碼肯定大致方向上是一致的。只不過spring有專門的建構函式解析器等封裝的比較好的類,這裡最麻煩的是構造函式引數的處理,這裡不建議深究,先弄懂主流程。不過,需要知道的是,不論是建構函式還是屬性,一旦有個@autowird或者@resource註解,都會觸發beanfactory的getbean()方法,而這個方法,就是本文講的內容,這裡有點遞迴的意思。這也是spring解決迴圈依賴的基礎。

初步建立出bean之後,是不是就該做屬性注入了?在這之前,spring還做了一件事。

經典的postprocessor介面呼叫,我在註解上有些,這裡有包括我們經常用的@postconstruct,@predestroy,@resource,@autowired,@value等註解的支援。具體大家可以點進對應的實現類中看到的實現過程細節。由於篇幅關係,實在不能每個點都涉及。

做完這些基礎工作之後

接下去有3個很重要的方法,新增**快取,依賴注入,及例項化之後的呼叫。

這裡我們先看第二個方法依賴注入

重點是這一塊**

我們選我們最熟悉的autowired來看看是怎麼完成依賴注入的

spring原始碼常用手段,先收集再處理,這裡先收集註解資訊包裝成注入元資料,這裡就大家自行點進去看,思路其實和我們自己做也沒什麼區別,反射獲取class資訊,獲取屬性上的註解,和註解中的屬性值,像autowired的required屬性的value,然後去容器中找相對應的bean,反射賦值。

最後再看第三個方法

這裡完成了一些bean例項化之後的事情,比如aware(感知介面,我一般這麼叫)介面的方法呼叫,和之前提過的後置處理器的呼叫,像我們常用的@postcontruct註解,在初始化完成後要呼叫的方法。值得一提的是,這裡也是aop**類生成的入口。

我們不妨猜一下,它是怎麼做的。

如果需要生成**類,則生成,具體怎麼生成,之後看到aop的原始碼時會講。面試的時候,你也不能光說,動態**,jdk動態**和cglib2種,然後就沒了。

那麼ioc建立例項的整個大過程,差不多就是這樣了,其中有很多的細節,具體做了什麼,確實因為文字的原因,無法面面俱到,我相信看到這篇文章的同學, 肯定是處於學習階段,我希望大家一定要多跟幾遍原始碼,自己多想多看。

spring再學習(二) spring事務

與關係型資料庫一致,事務都遵循 acid 原則 spring支援程式設計式事務管理以及宣告式事務管理兩種方式。在spring框架,用註解開啟事務 transactional,當然事務有其特性 spring事務的傳播行為有7種 spring在事務中使用isolation來配置它 isolation r...

Spring原始碼學習(二) AOP

aop有些特有的概念,如 advisor advice和pointcut等等,使用或配置起來有點繞,讓人感覺有些距離感,其實它的實現就是一組標準的設計模式的組合使用 factory proxy chain of responsibility,只要搞清楚這幾個設計模式,讀aop的原始碼是比較容易的。首...

Spring原始碼學習

a spring 初始化的時候首先要執行的類為 org.springframework.web.context.contextloaderlistener 或 org.springframework.web.context.contextloaderservlet 接下來看一下在這個方法裡幹了寫什麼...