真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

在容器啟動(dòng)快完成時(shí),會(huì)把所有的單例bean進(jìn)行實(shí)例化,也可以叫做預(yù)先實(shí)例化。

在五通橋等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需網(wǎng)站設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),成都營(yíng)銷網(wǎng)站建設(shè),外貿(mào)營(yíng)銷網(wǎng)站建設(shè),五通橋網(wǎng)站建設(shè)費(fèi)用合理。

這樣做的好處之一是,可以及早地發(fā)現(xiàn)問題,及早的拋出異常,及早地解決掉。

本文就來看下整個(gè)的實(shí)例化過程。其實(shí)還是比較繁瑣的。

一、從容器中找出所有的bean定義名稱

因?yàn)椴恢勒l(shuí)是單例bean,所以只能先全部找出來。如下圖01:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

二、循環(huán)遍歷所有的bean名稱,檢查是否符合條件

首先要合并bean定義,因?yàn)閎ean定義可以有父子關(guān)系,類似繼承。

然后這個(gè)合并后的bean定義必須是,非抽象的,單例的,非延遲初始化的。

那么它就滿足條件,如下圖02:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

三、判斷是否為FactoryBean類型

如果不是的話,說明該beanName對(duì)應(yīng)一個(gè)普通的bean,可以直接實(shí)例化。

如果是的話,說明該beanName對(duì)應(yīng)的是一個(gè)工廠,這個(gè)工廠本身是單例的。

但是它里面生產(chǎn)的bean不一定是單例的。即使是的話,還要判斷是否要積極的去初始化工廠里的bean。

具體的判斷如下圖03:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:提到FactoryBean類型,是否想起&符號(hào)的作用呢?

四、開始進(jìn)入眾所熟知的getBean(String name)方法

在上一圖中可以看到Spring對(duì)bean的實(shí)例化時(shí)竟然是調(diào)用的getBean(..)方法。

這樣共用一套代碼,簡(jiǎn)單省事。不僅如此,當(dāng)獲取一個(gè)bean的依賴時(shí),也可以用該方法。

這樣getBean(..)就是一個(gè)綜合方法,沒有bean實(shí)例就生成,有的話就直接返回。

如下圖04:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

五、對(duì)手工直接注冊(cè)的單例對(duì)象進(jìn)行檢測(cè)

bean實(shí)例除了可以用bean定義生成外,還可以由開發(fā)人員直接注冊(cè)一個(gè)bean實(shí)例。

這樣在使用bean定義生成實(shí)例前,先使用beanName去手動(dòng)注冊(cè)的bean實(shí)例集合中找一下。

如下圖05:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

如果找到了,就不用生成了,否則就會(huì)根據(jù)bean定義生成bean實(shí)例。

六、對(duì)FactoryBean類型的檢測(cè)

這和上面提到的是一個(gè)類型,它是一個(gè)工廠,可以認(rèn)為是包裹在了實(shí)際bean實(shí)例的外面。

這樣可以有一些特殊的作用,不好之處就是每次都要檢測(cè)下,然后從它內(nèi)部拿出實(shí)際的bean實(shí)例。

具體檢測(cè)過程不再展開,如下圖06:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

七、對(duì)類型進(jìn)行轉(zhuǎn)換,如果有必要的話

上面我們僅僅是用beanName去手動(dòng)注冊(cè)的實(shí)例集合中尋找,萬一這個(gè)手動(dòng)注冊(cè)的實(shí)例類型和bean定義要求的不兼容呢?

因此要進(jìn)行類型檢測(cè)與轉(zhuǎn)換,實(shí)在不行就拋異常,如下圖07:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

如果成功的話,就表明手動(dòng)注冊(cè)的bean定義實(shí)例滿足要求,將它返回即可。

注:如果在第五步?jīng)]有找到beanName對(duì)應(yīng)的手動(dòng)注冊(cè)的bean實(shí)例,那開始根據(jù)bean定義來生成bean實(shí)例。繼續(xù)往下看。

八、準(zhǔn)備好顯式指定的依賴,如@DependsOn指定的

先獲取合并后的bean定義,然后從中讀出顯式指定的依賴,并逐個(gè)處理。

使用registerDependentBean(..)將依賴關(guān)系寫入容器,由容器維護(hù)。

并同樣使用getBean(..)方法實(shí)例化這些依賴,一模一樣的套路。

其實(shí)就是遞歸,如下圖08:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:接下來使用createBean(..)方法正式開始創(chuàng)建bean

九、解析出bean的Class

因?yàn)樵谧?cè)bean定義時(shí)并不一定加載類,可能只是一個(gè)字符串的類名稱。

所以要根據(jù)類名稱去加載類,并得到類的Class。如下圖09:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

十、調(diào)用bean后處理器的postProcessBeforeInstantiation方法

此時(shí)還處在實(shí)例化之前,讓用戶有機(jī)會(huì)來提供一個(gè)bean實(shí)例或代理。

這樣Spring就不再進(jìn)行后續(xù)的實(shí)例化步驟,直接返回這個(gè)用戶提供的。

如果用戶沒有提供的話,Spring繼續(xù)后續(xù)的處理。如下圖1011:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

十一、調(diào)用InstanceSupplier生成bean實(shí)例,如果有的話

在注冊(cè)bean定義時(shí),可以設(shè)置一個(gè)Supplier類型的函數(shù)式接口。

其實(shí)就是用戶可以提供一段創(chuàng)建bean實(shí)例的代碼,這樣Spring就使用它來創(chuàng)建bean實(shí)例。

然后將這個(gè)實(shí)例返回即可,如下圖12:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

十二、通過FactoryMethod來生成bean實(shí)例,如果FactoryMethodName不為null的話

如下圖13:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

FactoryMethod就是工廠方法,說明bean的實(shí)例是通過調(diào)用這個(gè)工廠方法返回的,而不是通過反射調(diào)用構(gòu)造函數(shù)返回的。

工廠方法有兩種,靜態(tài)的和實(shí)例的。如果是實(shí)例的,那還要有一個(gè)FactoryBeanName來指定一個(gè)bean名稱,根據(jù)它可以從容器中獲取一個(gè)對(duì)象,用作工廠。

如果是靜態(tài)的,那就不需要實(shí)例了,直接把bean定義中的類型作為工廠類即可。如下圖14:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

然后根據(jù)工廠方法的名稱,從bean定義中解析出對(duì)應(yīng)的Method對(duì)象。然后再解析出構(gòu)造方法參數(shù)用作工廠方法的參數(shù)。

最終通過反射調(diào)用這個(gè)工廠方法,獲取返回值,就是bean實(shí)例了,如下圖15:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

這個(gè)bean實(shí)例會(huì)用一個(gè)BeanWrapper接口進(jìn)行包裝,這個(gè)接口提供一些基礎(chǔ)的JavaBean功能,如數(shù)據(jù)的類型轉(zhuǎn)換然后再進(jìn)行屬性綁定等。

十三、調(diào)用bean后處理器的determineCandidateConstructors方法來確定候選構(gòu)造方法

如下圖16:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

這里涉及到從多個(gè)候選構(gòu)造方法中選出一個(gè)最合適的,是一個(gè)比較復(fù)雜的過程。

最后也是通過反射調(diào)用構(gòu)造方法,獲取到bean的實(shí)例。如下圖17:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

然后也用BeanWrapper接口進(jìn)行包裝。

十四、使用更適合的構(gòu)造方法來實(shí)例化,如果有的話

如果上一步?jīng)]有執(zhí)行的話,則使用bean定義中更適合的構(gòu)造方法,如下圖18:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

十五、使用默認(rèn)無參的構(gòu)造方法來實(shí)例化

如果上一步?jīng)]有執(zhí)行的話,則使用默認(rèn)無參構(gòu)造方法,如下圖19:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:至此bean實(shí)例已經(jīng)創(chuàng)建好了。

十六、應(yīng)用bean后處理器的postProcessMergedBeanDefinition方法

上兩篇文章詳細(xì)介紹了bean后處理器,主要是用來實(shí)現(xiàn)注解的功能的。

如下圖2021:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

十七、此時(shí)就可以暴露早期的bean引用了,如果需要的話

如允許循環(huán)引用的話,就需要這個(gè)操作,如下圖22:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

十八、應(yīng)用bean后處理器的postProcessAfterInstantiation方法

如下圖23:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

且該方法如果返回false,該bean實(shí)例后續(xù)的bean后處理器操作將不再執(zhí)行。

十九、根據(jù)設(shè)置的自動(dòng)裝配類型處理自動(dòng)裝配問題

如下圖24:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

如果配置的是按名稱自動(dòng)裝配,則會(huì)把所有setter方法中參數(shù)類型是非基本類型的都找出來。

然后按照屬性名稱從容器中找出同名的bean,作為屬性值保存起來以備后用。如下圖25:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

如果配置的是按類型自動(dòng)裝配,則會(huì)把所有setter方法中參數(shù)類型是非基本類型的都找出來。

然后按照屬性類型從容器中解析出對(duì)應(yīng)的bean,作為屬性值保存起來以備后用。如下圖26:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:以上的setter方法上不需要標(biāo)任何注解,因?yàn)轱@式設(shè)置了自動(dòng)裝配類型。

而默認(rèn)情況其實(shí)是沒有設(shè)置的,即AUTOWIRE_NO,所以我們要標(biāo)上@Autowired注解。

二十、應(yīng)用bean后處理器的postProcessProperties方法

在這一步其實(shí)是完成了依賴的注入,如下圖27:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

二十一、其余屬性值到bean屬性的綁定

這一步是由BeanWrapper這個(gè)接口完成的,如下圖28:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:至此bean的所有依賴裝配和屬性設(shè)置都已完畢。

二十二、應(yīng)用bean后處理器的postProcessBeforeInitialization方法

這一步就開始執(zhí)行初始化方法了。如下圖2930:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

二十三、執(zhí)行bean的初始化方法afterPropertiesSet()

如果bean實(shí)現(xiàn)了InitializingBean接口,此刻會(huì)調(diào)用它唯一的方法。

如下圖31:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

二十四、執(zhí)行bean定義中指定的初始化方法initMethod

如果bean定義是使用@Bean注冊(cè)的,可以通過設(shè)置注解屬性指定初始化方法。

如下圖32:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:三種可以指定初始化的方法:

1)@PostConstruct注解,

2)InitializingBean接口,

3)@Bean注解

這里有兩個(gè)問題需要記?。?/p>

1)如果兩種或三種方式都指向了同一個(gè)方法,這個(gè)方法也只會(huì)被執(zhí)行一次。

2)三種方式指定的初始化方法的執(zhí)行順序就按剛剛列出的1、2、3這個(gè)順序。

二十五、應(yīng)用bean后處理器的postProcessAfterInitialization方法

如下圖33、34:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:至此bean的初始化工作已經(jīng)完成。

二十六、注冊(cè)bean銷毀時(shí)要執(zhí)行的代碼,如果需要的話

除了使用了之前說過的三種方式指定過銷毀發(fā)方法之外,如果bean實(shí)現(xiàn)了AutoCloseable接口也算。

如果使用@Bean注冊(cè)且沒有指定銷毀方法,那么默認(rèn)把close和shutdown方法作為銷毀方法。

這些情況都是需要注冊(cè)的,如下圖35:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

注:至此bean實(shí)例本身已經(jīng)準(zhǔn)好了。

二十七、緩存單例的bean

如果這個(gè)bean是單例的,而且是新創(chuàng)建的,會(huì)把它緩存到容器里,以備后用。

如下圖36:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

二十八、進(jìn)行Scope處理

如果一個(gè)bean指定了Scope,即它的生命周期既非單例也非原型而是屬于某一個(gè)范圍。

Spring暫時(shí)支持的范圍如下圖37:

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

實(shí)現(xiàn)原理其實(shí)很簡(jiǎn)單,比如Session范圍,那就先從Session中獲取,沒有的話生成一個(gè)放入Session中即可。

二十九、對(duì)FactoryBean類型的檢測(cè)與處理

剛剛創(chuàng)建的這個(gè)bean可能是FactoryBean類型,即一個(gè)工廠。而我們想要的可能是工廠里生成的bean。

簡(jiǎn)單來說,那就從工廠中把bean拿出來即可。

三十、類型的檢測(cè)與轉(zhuǎn)換

最終得到的bean實(shí)例可能與期望的類型不兼容,此時(shí)就要進(jìn)行類型轉(zhuǎn)換。

轉(zhuǎn)換成功的話就返回,失敗的話就拋出類型不匹配異常。

至此一個(gè)bean的創(chuàng)建工作已經(jīng)全部結(jié)束。

整體流程步驟就是這樣,只是忽略了一些和流程無關(guān)的細(xì)節(jié)實(shí)現(xiàn)。

點(diǎn)擊獲取?附送學(xué)習(xí)進(jìn)階架構(gòu)資料、PDF書籍文檔、面試資料

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建

品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建


當(dāng)前文章:品Spring:動(dòng)手才知道,三十步才能完成一個(gè)bean實(shí)例的創(chuàng)建
轉(zhuǎn)載來源:http://weahome.cn/article/gdedpd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部