隨筆 - 12, 文章 - 0, 評(píng)論 - 5, 引用 - 0
          數(shù)據(jù)加載中……

          Spring AOP源于生活的原理(一)

          AOP原理

                    spring用代理類包裹切面,把他們織入到Spring管理的bean中。也就是說代理類偽裝成目標(biāo)類,它會(huì)截取對(duì)目標(biāo)類中方法的調(diào)用,讓調(diào)用者對(duì)目標(biāo)類的調(diào)用都先變成調(diào)用偽裝類,偽裝類中就先執(zhí)行了切面,再把調(diào)用轉(zhuǎn)發(fā)給真正的目標(biāo)bean。 


          生活中的AOP

          現(xiàn)在可以自己想一想,怎么搞出來這個(gè)偽裝類,才不會(huì)被調(diào)用者發(fā)現(xiàn)(過JVM的檢查,JAVA是強(qiáng)類型檢查,哪里都要檢查類型)。 
          實(shí)現(xiàn)和目標(biāo)類相同的接口,我也實(shí)現(xiàn)和你一樣的接口,反正上層都是接口級(jí)別的調(diào)用,這樣我就偽裝成了和目標(biāo)類一樣的類(實(shí)現(xiàn)了同一接口,咱是兄弟了),也就逃過了類型檢查,到j(luò)ava運(yùn)行期的時(shí)候,利用多態(tài)的后期綁定(所以spring采用運(yùn)行時(shí)),偽裝類(代理類)就變成了接口的真正實(shí)現(xiàn),而他里面包 裹了真實(shí)的那個(gè)目標(biāo)類,最后實(shí)現(xiàn)具體功能的還是目標(biāo)類,只不過偽裝類在之前干了點(diǎn)事情(寫日志,安全檢查,事物等)。 

          兄弟模式

          生活解析

          這就好比,一個(gè)人讓你辦件事,每次這個(gè)時(shí)候,你弟弟就會(huì)先出來,當(dāng)然他分不出來了,以為是你,你這個(gè)弟弟雖然辦不了這事,但是他知道你能辦,所以就答應(yīng)下來了,并且收了點(diǎn)禮物(寫日志),收完禮物了,給把事給人家辦了啊,所以你弟弟又找你這個(gè)哥哥來了,最后把這是辦了的還是你自己。但是你自己并不知道你弟弟已經(jīng)收禮物了,你只是專心把這件事情做好。 

          在兄弟模式中spring會(huì)使用JDK的java.lang.reflect.Proxy類,它允許Spring動(dòng)態(tài)生成一個(gè)新類來實(shí)現(xiàn)必要的接口,織入通知,并且把對(duì)這些接口的任何調(diào)用都轉(zhuǎn)發(fā)到目標(biāo)類。

          實(shí)際理論

          JDK動(dòng)態(tài)代理:其代理對(duì)象必須是某個(gè)接口的實(shí)現(xiàn),它是通過在運(yùn)行期間創(chuàng)建一個(gè)接口的實(shí)現(xiàn)類來完成對(duì)目標(biāo)對(duì)象的代理。

           父子模式

              生活解析

          順著這個(gè)思路想,要是本身這個(gè)類就沒實(shí)現(xiàn)一個(gè)接口呢,你怎么偽裝我,我就壓根沒有機(jī)會(huì)讓你搞出這個(gè)雙胞胎的弟弟,那么就用第2種代理方式,創(chuàng)建一個(gè)目標(biāo)類的子類,生個(gè)兒子,讓兒子偽裝我 。

           生成子類調(diào)用,這次用子類來做為偽裝類,當(dāng)然這樣也能逃過JVM的強(qiáng)類型檢查,我繼承的嗎,當(dāng)然查不出來了,子類重寫了目標(biāo)類的所有方法,當(dāng)然在這些重寫的方法中,不僅實(shí)現(xiàn)了目標(biāo)類的功能,還在這些功能之前,實(shí)現(xiàn)了一些其他的(寫日志,安全檢查,事物等)。 

          這次的對(duì)比就是,兒子先從爸爸那把本事都學(xué)會(huì)了,所有人都找兒子辦事情,但是兒子每次辦和爸爸同樣的事之前,都要收點(diǎn)小禮物(寫日志),然后才去辦真正的事。當(dāng)然爸爸是不知道兒子這么干的了。 這里就有件事情要說,某些本事是爸爸獨(dú)有的(final的),兒子學(xué)不了,學(xué)不了就辦不了這件事,辦不了這個(gè)事情,自然就不能收人家禮了。  

          在父子模式中spring使用CGLIB庫(kù)生成目標(biāo)類的一個(gè)子類,在創(chuàng)建這個(gè)子類的時(shí)候,spring織入通知,并且把對(duì)這個(gè)子類的調(diào)用委托到目標(biāo)類。 

          實(shí)際理論

          CGLIB代理:實(shí)現(xiàn)原理類似于JDK動(dòng)態(tài)代理,只是它在運(yùn)行期間生成的代理對(duì)象是針對(duì)目標(biāo)類擴(kuò)展的子類。CGLIB是高效的代碼生成包,底層是依靠ASM(開源的java字節(jié)碼編輯類庫(kù))操作字節(jié)碼實(shí)現(xiàn)的,性能比JDK強(qiáng)。

          兩種模式總結(jié)

          相比之下,兄弟模式好些,它能更好的實(shí)現(xiàn)松耦合,尤其在今天都高喊著面向接口編程的情況下,父子模式只是在沒有實(shí)現(xiàn)接口的時(shí)候,也能織入通知,應(yīng)當(dāng)做一種例外。

          posted on 2012-07-19 22:20 拼搏 閱讀(855) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 新晃| 吉隆县| 沙河市| 荆州市| 枣庄市| 灵宝市| 偃师市| 陆良县| 全州县| 二手房| 沛县| 婺源县| 习水县| 高台县| 张家口市| 彭泽县| 泰和县| 汨罗市| 彝良县| 子洲县| 丹凤县| 怀集县| 南安市| 视频| 綦江县| 夏邑县| 武清区| 华宁县| 青阳县| 临夏市| 平果县| 清河县| 通许县| 西吉县| 义乌市| 彭山县| 城步| 浙江省| 安远县| 合山市| 绥江县|