久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

瀏覽:76日期:2023-08-10 16:02:30

實例化方法,把bean實例化,并且包裝成BeanWrapper

1、點進這個方法里面。

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

這個方法是反射調(diào)用類中的 factoryMethod 方法。 這要知道@Bean 方法的原理, 實際上spring 會掃描有@bean 注解的方法, 然后把方法名稱設(shè)置到 BeanDefinition 的 factoryMethod屬性中, 接下來就會調(diào)到上面截圖中的方法實現(xiàn)@Bean 方法的調(diào)用。

2、 有參構(gòu)造函數(shù)的時候

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

determineConstructorsFromBeanPostProcessors這個方法是 BeanPostProcessor 接口類的首次應(yīng)用, 最終會掉到AutowiredAnnotationBeanPostProcessor 類的方法, 在方法中會掃描有注解的構(gòu)造函數(shù)然后完成裝配過程。 然后把有有@Autowired 注解的構(gòu)造函數(shù)返回。

3、 無參構(gòu)造函數(shù)的實例化

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

這就是簡單的反射實例化。 大部分類的實例化都會走這個邏輯

4、 類中注解的收集

實例化完成后接下來就需要對類中的屬性進行依賴注入操作, 但是類里面屬性和方法的依賴注入往往用@Autowired 或者@Resource 注解, 那么這些注解的依賴注入是如何完成的呢?

注解的收集:

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

也是通過 BeanPostProcessor 接口類型實例來挨個處理的。

A、 首先是CommonAnnotationBeanPostProcessor 類, 這個類完成了@Resource 注解的屬性或者方法的收集

這個類還對@PostConstruct 和@PreDestory 支持

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

收集過程

1、 看緩存里面有沒有 InjectionMetadata 對象

2、 從類中獲取所有 Field 對象, 循環(huán) field 對象, 判斷 field 有沒有@Resource 注解,如果有注解封裝成 ResourceElement 對象

3、 從類中獲取所有 Method 對象, 循環(huán) Method 對象, 判斷 Method 有沒有@Resource

注解, 如果有注解封裝成 ResourceElement 對象

4、 最終把兩個 field 和 Method 封裝的對象集合封裝到 InjectionMetadata 對象中

B、 然后是AutowiredAnnotationBeanPostProcessor 類, 對@Autowired 注解的屬性和方法的收集。 收集過程基本上跟@Resource 注解的收集差不多, 這里就不贅述了

5、 IOCDI 依

對應(yīng)的方法:

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

這里又是一個 BeanPostProcessor 類型接口的運用, 前面我們講到了@Resource@Autowired 注解的收集, 那么這個方法就是根據(jù)收集到的注解進行反射調(diào)用。

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

循環(huán)收集到的 metaData 中的 list 對象, 然后挨個調(diào)用里面的 InjectedElement 的inject 方法完成依賴注入。

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

其中 value 值的獲取, 如果依賴的屬性是一個引用類型必定會觸發(fā)該屬性的BeanFactory.getBean 操作, 從而從 spring 容器中獲取到對應(yīng)的實例。 方法的依賴注入類似這里就不再贅述。

6、 bean 實例化后的操作

代碼走到這里:

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

A、 首先是對某些 Aware 接口的調(diào)用

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

B、 然后@PostConstruct 注解方法的調(diào)用

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

這里又是一個 BeanPostProcessor 接口的運用,前面講過, 有@PostConstruct 注解的方法會收集到一個 met就是通過 BeanPostProcessor 接口調(diào)到CommonAnnotationBeanPostProcessor 類, 然后在類中拿根據(jù)對象里面的容器來反射調(diào)用有注解的方法。 代碼如下:

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

有@PostConstruct 注解的容器會收集到 initMethods 容器中, 接下來就是方法的

反射調(diào)用。

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

C、 InitializingBean 接口和 init-method 屬性調(diào)用

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

Init-method 屬性調(diào)用是在 afterPropertiesSet 之后

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

afterPropertiesSet和Init-method和有@PostConstruct注解的方法其實核心功能都是一樣的, 只是調(diào)用時序不一樣而已, 都是在該類實例化和 IOC 做完后調(diào)用的, 我們可以在這些方法中做一些在 spring 或者 servlet 容器啟動的時候的初始化工作。 比如緩存預(yù)熱, 比如緩存數(shù)據(jù)加載到內(nèi)存, 比如配置解析, 等等初始化工作。

在這個方法里面還有一個重要的邏輯

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

也是一個 BeanPostProcessor 接口的運用, 在這里會返回 bean 的代理實例, 這個就是 AOP 的入口。

D、 FactoryBean 接口

帶入如下:

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

在實例化和 IOC/DI 做完后, 就會調(diào)用 FactoryBean 類型的接口, 如果要獲取到FactoryBean 類本身, 就必須加上”&”符號, 比如beanFactory.getBean(“&beanName” )。

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

BeanFactory.getBean(“beanName”)只能獲取到getObject()方法返回的實例。

getObject方法返回的實例會有單獨的緩存存儲, 跟其他實例不是同一個緩存, 對應(yīng)的緩存是:factoryBeanObjectCache

E、 循環(huán)依賴

循環(huán)依賴請參照流程圖理解https://www.processon.com/view/link/5df9ce52e4b0c4255ea1a84f

循環(huán)依賴只會出現(xiàn)在單例實例無參構(gòu)造函數(shù)實例化情況下

有參構(gòu)造函數(shù)的加@Autowired 的方式循環(huán)依賴是直接報錯的, 多例的循環(huán)依賴也是直接報錯的

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用

循環(huán)依賴步驟:

1、 A 類無參構(gòu)造函數(shù)實例化后, 設(shè)置三級緩存

2、 A 類 populateBean 進行依賴注入, 這里觸發(fā)了 B 類屬性的 getBean 操作

3、 B 類無參構(gòu)造函數(shù)實例化后, 設(shè)置三級緩存

4、 B 類 populateBean 進行依賴注入, 這里觸發(fā)了 A 類屬性的 getBean 操作

5、 A 類之前正在實例化, singletonsCurrentlyInCreation 集合中有已經(jīng)有這個 A 類了, 三級緩存里面也有了, 所以這時候是從三級緩存中拿到的提前暴露的A 實例, 該實例還沒有進行 B 類屬性的依賴注入的, B 類屬性為空。

6、 B 類拿到了 A 的提前暴露實例注入到 A 類屬性中了

7、 B 類實例化已經(jīng)完成, B 類的實例化是由 A 類實例化中 B 屬性的依賴注入觸發(fā)的 getBean 操作進行的, 現(xiàn)在 B 已經(jīng)實例化, 所以 A 類中 B 屬性就可以完成依賴注入了, 這時候 A 類 B 屬性已經(jīng)有值了

8、 B 類 A 屬性指向的就是 A 類實例堆空間, 所以這時候 B 類 A 屬性也會有值了。

總結(jié)

到此這篇關(guān)于spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用的文章就介紹到這了,更多相關(guān)spring源碼bean的初始化及循環(huán)引用內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 亚洲一区在线日韩在线深爱 | 久久永久视频 | 91视频国产一区 | 亚洲精品久久久久久久久久久 | 中字幕视频在线永久在线观看免费 | 一本久久a久久精品亚洲 | 成人欧美一区二区三区黑人孕妇 | 成人在线视频一区二区 | 一级欧美 | 成人av影院 | 国产精品第一国产精品 | 成人午夜电影在线 | 国产精品爱久久久久久久 | 伊人春色网| 天天宗合网 | 国产精品欧美久久久久一区二区 | 一本一道久久久a久久久精品91 | 黄色免费网站在线看 | 国产精品一区在线观看你懂的 | 亚洲女人的天堂 | 91资源总站 | 亚州中文字幕 | 精品日韩欧美一区二区在线播放 | 久久综合一区二区 | 天天操天天干视频 | 久久久久综合 | 成人久久久精品乱码一区二区三区 | 色999视频 | 成人影院一区二区三区 | 精品国产一区二区 | 亚洲精品日韩在线 | 国产精品国产精品国产专区不卡 | 一级a毛片 | 黄色91| 欧美激情国产日韩精品一区18 | 久久91视频 | 一级在线毛片 | 欧美一区| 九九热精品免费视频 | 精品亚洲一区二区三区 | 美女天天操 |