欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2020年10月02日 12:00:47   作者:開(kāi)心的魚(yú)a1  
這篇文章主要給大家介紹了關(guān)于spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

實(shí)例化方法,把bean實(shí)例化,并且包裝成BeanWrapper

1、點(diǎn)進(jìn)這個(gè)方法里面。

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

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

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

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

這就是簡(jiǎn)單的反射實(shí)例化。 大部分類(lèi)的實(shí)例化都會(huì)走這個(gè)邏輯

4、 類(lèi)中注解的收集

實(shí)例化完成后接下來(lái)就需要對(duì)類(lèi)中的屬性進(jìn)行依賴(lài)注入操作, 但是類(lèi)里面屬性和方法的依賴(lài)注入往往用@Autowired 或者@Resource 注解, 那么這些注解的依賴(lài)注入是如何完成的呢?

注解的收集:

也是通過(guò) BeanPostProcessor 接口類(lèi)型實(shí)例來(lái)挨個(gè)處理的。

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

這個(gè)類(lèi)還對(duì)@PostConstruct 和@PreDestory 支持

收集過(guò)程

1、 看緩存里面有沒(méi)有 InjectionMetadata 對(duì)象

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

3、 從類(lèi)中獲取所有 Method 對(duì)象, 循環(huán) Method 對(duì)象, 判斷 Method 有沒(méi)有@Resource

注解, 如果有注解封裝成 ResourceElement 對(duì)象

4、 最終把兩個(gè) field 和 Method 封裝的對(duì)象集合封裝到 InjectionMetadata 對(duì)象中

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

5、 IOC\DI 依

對(duì)應(yīng)的方法:

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

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

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

6、 bean 實(shí)例化后的操作

代碼走到這里:

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

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

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

有@PostConstruct 注解的容器會(huì)收集到 initMethods 容器中, 接下來(lái)就是方法的

反射調(diào)用。

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

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

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

在這個(gè)方法里面還有一個(gè)重要的邏輯

也是一個(gè) BeanPostProcessor 接口的運(yùn)用, 在這里會(huì)返回 bean 的代理實(shí)例, 這個(gè)就是 AOP 的入口。

D、 FactoryBean 接口

帶入如下:

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


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

getObject方法返回的實(shí)例會(huì)有單獨(dú)的緩存存儲(chǔ), 跟其他實(shí)例不是同一個(gè)緩存, 對(duì)應(yīng)的緩存是:factoryBeanObjectCache

E、 循環(huán)依賴(lài)

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

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

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

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

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

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

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

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

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

6、 B 類(lèi)拿到了 A 的提前暴露實(shí)例注入到 A 類(lèi)屬性中了

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

8、 B 類(lèi) A 屬性指向的就是 A 類(lèi)實(shí)例堆空間, 所以這時(shí)候 B 類(lèi) A 屬性也會(huì)有值了。

總結(jié)

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

相關(guān)文章

  • springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程

    springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程

    這篇文章主要介紹了springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • 微信公眾號(hào)測(cè)試賬號(hào)自定義菜單的實(shí)例代碼

    微信公眾號(hào)測(cè)試賬號(hào)自定義菜單的實(shí)例代碼

    這篇文章主要介紹了微信公眾號(hào)測(cè)試賬號(hào)自定義菜單的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • 關(guān)于Mybatis中foreach遍歷Map的實(shí)現(xiàn)示例

    關(guān)于Mybatis中foreach遍歷Map的實(shí)現(xiàn)示例

    這篇文章主要介紹了關(guān)于Mybatis中foreach遍歷Map的實(shí)現(xiàn)示例,MyBatis?是一款優(yōu)秀的半自動(dòng)的ORM持久層框架,它支持自定義?SQL、存儲(chǔ)過(guò)程以及高級(jí)映射,需要的朋友可以參考下
    2023-05-05
  • MyBatisPlus分頁(yè)的同時(shí)指定排序規(guī)則說(shuō)明

    MyBatisPlus分頁(yè)的同時(shí)指定排序規(guī)則說(shuō)明

    這篇文章主要介紹了MyBatisPlus分頁(yè)的同時(shí)指定排序規(guī)則說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • springboot項(xiàng)目實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能

    springboot項(xiàng)目實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能

    這篇文章主要介紹了springboot項(xiàng)目實(shí)現(xiàn)斷點(diǎn)續(xù)傳,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • java中set接口使用方法詳解

    java中set接口使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了java中set接口使用方法,介紹了Java中Set集合接口實(shí)現(xiàn)插入對(duì)象不重復(fù)的原理,感興趣的小伙伴們可以參考一下
    2016-05-05
  • SpringBoot參數(shù)驗(yàn)證的幾種方式小結(jié)

    SpringBoot參數(shù)驗(yàn)證的幾種方式小結(jié)

    在日常的接口開(kāi)發(fā)中,為了防止非法參數(shù)對(duì)業(yè)務(wù)造成影響,經(jīng)常需要對(duì)接口的參數(shù)進(jìn)行校驗(yàn),例如登錄的時(shí)候需要校驗(yàn)用戶(hù)名和密碼是否為空,所以本文介紹了SpringBoot參數(shù)驗(yàn)證的幾種方式,需要的朋友可以參考下
    2024-07-07
  • 深入了解Java中Synchronized關(guān)鍵字的實(shí)現(xiàn)原理

    深入了解Java中Synchronized關(guān)鍵字的實(shí)現(xiàn)原理

    synchronized是JVM的內(nèi)置鎖,基于Monitor機(jī)制實(shí)現(xiàn),每一個(gè)對(duì)象都有一個(gè)與之關(guān)聯(lián)的監(jiān)視器?(Monitor),這個(gè)監(jiān)視器充當(dāng)了一種互斥鎖的角色,本文就詳細(xì)聊一聊Synchronized關(guān)鍵字的實(shí)現(xiàn)原理,需要的朋友可以參考下
    2023-06-06
  • 關(guān)于spring data jpa一級(jí)緩存的問(wèn)題

    關(guān)于spring data jpa一級(jí)緩存的問(wèn)題

    這篇文章主要介紹了關(guān)于spring data jpa一級(jí)緩存的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java代理模式的示例詳解

    Java代理模式的示例詳解

    代理模式(Proxy?Parttern)為一個(gè)對(duì)象提供一個(gè)替身,來(lái)控制這個(gè)對(duì)象的訪問(wèn),即通過(guò)代理對(duì)象來(lái)訪問(wèn)目標(biāo)對(duì)象。本文將通過(guò)示例詳細(xì)講解一下這個(gè)模式,需要的可以參考一下
    2022-08-08

最新評(píng)論