摘要:讀取定義的內(nèi)容,將用戶定義的表示成,是在容器中對的抽象,記錄了配置的信息。的生命周期在初始化后,并沒有被實(shí)際的創(chuàng)建。工作過程當(dāng)目標(biāo)對象被調(diào)用時(shí),會觸發(fā)的回調(diào)函數(shù)進(jìn)行攔截。
IoC容器的實(shí)現(xiàn)
控制反轉(zhuǎn)(Inversion of Control,縮寫為IoC),是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來減低計(jì)算機(jī)代碼之間的耦合度。
依賴反轉(zhuǎn)是什么依賴反轉(zhuǎn)在Spring中的體現(xiàn)是依賴注入。
類通過引用來進(jìn)行合作,這種引用形成了類之間的依賴,如果這種依賴關(guān)系需要對象自己管理,那么代碼會產(chǎn)生高度的耦合,導(dǎo)致開發(fā)和測試上的困難。如果這種依賴的管理交給框架來做,將簡化面向?qū)ο笙到y(tǒng)的復(fù)雜性,這就是依賴的反轉(zhuǎn)。
Spring中的容器是什么容器用來管理應(yīng)用中的對象和其之間的依賴關(guān)系。BeanFactory是對容器的一種抽象,ApplicationContext是其高級實(shí)現(xiàn)。
IoC的初始化過程整體過程分三步:
Resourece定位,也就是定位定義Bean資源的位置。Resourece的位置是多樣的,使用比較多的是FileSystemResourece。
BeanDefinition載入。讀取定義的內(nèi)容,將用戶定義的Bean表示成BeanDefinition,BeanDefinition是在容器中對POJO的抽象,記錄了配置的bean信息。
向IoC容器注冊BeanDefinition,IoC用HashMap結(jié)構(gòu)來維護(hù)注冊的BeanDefinition。
注意這里只是有Bean的載入,而不是依賴注入,依賴注入發(fā)生在第一次通過getBean向容器獲取Bean的時(shí)候。
依賴注入過程在發(fā)起getBean方法時(shí),才會進(jìn)行依賴注入,創(chuàng)建響應(yīng)的bean。
依賴注入過程如下:
判斷單例bean是否已經(jīng)創(chuàng)建,創(chuàng)建過的無需重復(fù)創(chuàng)建。
遞歸創(chuàng)建依賴的bean。
最后創(chuàng)建目標(biāo)bean實(shí)例。
實(shí)例化Java對象。采用了CGLIB或者JVM反射機(jī)制來生成對象。CGLIB可以在運(yùn)行期動態(tài)的生成新的class。
注入屬性依賴。
Bean的生命周期在IoC初始化后,Bean并沒有被實(shí)際的創(chuàng)建。在getBean后,才會有bean的實(shí)例化,bean的生命周期如下:
創(chuàng)建bean實(shí)例->設(shè)置bean的屬性->調(diào)用bean的初始化方法(initialization)->應(yīng)用可以使用bean->容器關(guān)閉,銷毀bean
Bean的lazy init上述可知,bean會在使用時(shí)才會真正的創(chuàng)建,這防止了創(chuàng)建大量用不到的bean實(shí)例。
當(dāng)然,可以通過設(shè)置參數(shù),讓bean在IoC容器初始化完畢后就創(chuàng)建。
IoC感知的BeanBean一般情況下不需要知道IoC容器的存在,有時(shí)候則需要。Bean可以實(shí)現(xiàn)一些aware接口來獲得想要的容器屬性。
如ApplicationContextAware,可以在Bean中獲得上下文,從而在Bean中使用上下文。
AOP的實(shí)現(xiàn) AOP的作用分離關(guān)注點(diǎn)使解決特定領(lǐng)域問題的代碼從業(yè)務(wù)邏輯中獨(dú)立出來。
基本概念Advice通知:描述方法調(diào)用注入的切面行為。
Pointcut切點(diǎn):用來描述需要增強(qiáng)的方法集合。
Advisor通知器:將Advice和Pointcut結(jié)合起來。
在代理模式中,會設(shè)計(jì)一個(gè)和目標(biāo)對象有著一致接口的代理對象Proxy,客戶端對目標(biāo)對象的請求都會發(fā)送給代理對象,而客戶端對此毫無察覺。
該模式使得Proxy有機(jī)會對原始的對象的行為進(jìn)行一定的修改,可以在執(zhí)行前和執(zhí)行后分別執(zhí)行一定的動作,從而增強(qiáng)原始行為。
AopProxy的實(shí)現(xiàn)原理首先需要定義一些Advisor,這些Advisor定義了需要織入的增強(qiáng)功能,也就是涵蓋了通知的內(nèi)容。然后定義ProxyFactoryBean,它將會生成目標(biāo)的代理對象。在配置中,ProxyFactoryBean需要知道其代理的目標(biāo)是誰,代理的接口是哪個(gè),有哪些Advisor需要添加。
ProxyFactoryBean生成AopProxy過程:
初始化通知器鏈。通過getBean獲取通知器的bean,然后加入。ProxyFactoryBean只在第一次獲得AopProxy時(shí)初始化。
生成代理對象。
JDK生成,需要設(shè)置ClassLoader和代理接口。
CGLIB生成。
AopProxy工作過程:
當(dāng)目標(biāo)對象被調(diào)用時(shí),會觸發(fā)Proxy的回調(diào)函數(shù)進(jìn)行攔截。
首先獲取攔截器。從上述中初始化的通知器鏈中,遍歷并獲取匹配目標(biāo)方法的通知器,然后獲取通知器對應(yīng)的攔截器,該結(jié)果會被緩存。
調(diào)用器會依次迭代調(diào)用攔截器(interceptor)進(jìn)行增強(qiáng),最后調(diào)用目標(biāo)方法。
通知器封裝為攔截器:
攔截器默認(rèn)分為三類:MethodBeforeAdviceIntercepter、AfterReturn...、Throws...。
一個(gè)Advice會可能是MethodBeforeAdvice、AfterReturn...、Throws...其中的一個(gè)或者多個(gè)。
根據(jù)Advice的種類,適配器AdviceAdapter將其包裝為相應(yīng)的intercepter,intercepter中的invoke方法會根據(jù)before、after或者throw將advice的增強(qiáng)行為放置到適當(dāng)位置。適配器默認(rèn)是上述的三種,可以自定義adapter注冊進(jìn)來,以生成自己定制的intercepter。
調(diào)用器執(zhí)行攔截器鏈的時(shí)候,遞歸過程:process(調(diào)用器)->invoke(intercepter)->process(調(diào)用器)->invoke(下一個(gè)intercepter)...->目標(biāo)方法。所以intercepter會根據(jù)自己的種類在遞歸調(diào)用前或者后執(zhí)行advice的方法。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/70796.html
摘要:與容器與容器的關(guān)系為容器提供了宿主環(huán)境。容器通過初始化建立,是注冊在容器中的監(jiān)聽器,當(dāng)容器初始化時(shí),監(jiān)聽器會收到該事件從而發(fā)起容器的初始化。是處理請求的轉(zhuǎn)發(fā)器,從而響應(yīng)的請求。接著將數(shù)據(jù)進(jìn)行合并,然后將數(shù)據(jù)放入中進(jìn)行暴露。 Spring MVC 與 Web IoC容器與Web容器的關(guān)系 ServletContext為IoC容器提供了宿主環(huán)境。IoC容器通過ContexLoaderLis...
摘要:構(gòu)造函數(shù)注入通過調(diào)用類的構(gòu)造函數(shù),將接口實(shí)現(xiàn)類通過構(gòu)造函數(shù)變量傳入。而在中,其使用橫切技術(shù),將這類代碼從原屬的封裝對象中提取出來,封裝到一個(gè)可重用模塊中,稱為。 最近實(shí)習(xí)用到Spring的開發(fā)框架,但是之前沒有接觸過,因此希望利用網(wǎng)上的資源來學(xué)習(xí)以下。 Spring官方給出了非常全面的介紹,非常適合我這種完全的小白……在這一系列學(xué)習(xí)中,我閱讀的主要資源是5.1.2 Reference ...
摘要:我自己總結(jié)的學(xué)習(xí)的系統(tǒng)知識點(diǎn)以及面試問題,已經(jīng)開源,目前已經(jīng)。目前最新的版本中模塊的組件已經(jīng)被廢棄掉,同時(shí)增加了用于異步響應(yīng)式處理的組件。每一次請求都會產(chǎn)生一個(gè)新的,該僅在當(dāng)前內(nèi)有效。顯而易見,這種模式存在很多問題。 我自己總結(jié)的Java學(xué)習(xí)的系統(tǒng)知識點(diǎn)以及面試問題,已經(jīng)開源,目前已經(jīng) 41k+ Star。會一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎Star: https://githu...
摘要:會一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎中用到了那些設(shè)計(jì)模式中用到了那些設(shè)計(jì)模式這兩個(gè)問題,在面試中比較常見。工廠設(shè)計(jì)模式使用工廠模式可以通過或創(chuàng)建對象。 我自己總結(jié)的Java學(xué)習(xí)的系統(tǒng)知識點(diǎn)以及面試問題,已經(jīng)開源,目前已經(jīng) 41k+ Star。會一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎Star: https://github.com/Snailclimb... JDK 中用到了那...
摘要:開頭正式開啟我入職的里程,現(xiàn)在已是工作了一個(gè)星期了,這個(gè)星期算是我入職的過渡期,算是知道了學(xué)校生活和工作的差距了,總之,盡快習(xí)慣這種生活吧。當(dāng)時(shí)是看的廖雪峰的博客自己也用做爬蟲寫過幾篇博客,不過有些是在前人的基礎(chǔ)上寫的。 showImg(https://segmentfault.com/img/remote/1460000010867984); 開頭 2017.08.21 正式開啟我...
閱讀 2169·2021-11-12 10:36
閱讀 2158·2021-09-03 10:41
閱讀 2784·2021-08-19 10:57
閱讀 1247·2021-08-17 10:14
閱讀 1500·2019-08-30 15:53
閱讀 1220·2019-08-30 15:43
閱讀 983·2019-08-30 13:16
閱讀 2995·2019-08-29 16:56