Spring AOP的底層實現(xiàn)技術(shù)_第1頁
Spring AOP的底層實現(xiàn)技術(shù)_第2頁
Spring AOP的底層實現(xiàn)技術(shù)_第3頁
Spring AOP的底層實現(xiàn)技術(shù)_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

SpringAOP的底層實現(xiàn)技術(shù)一-JDK動態(tài)代理2008-12-3014:57JDK動態(tài)代理在JDK1.3以后提供了動態(tài)代理的技術(shù),允許開發(fā)者在運行期創(chuàng)建接口的代理實例。在Sun剛推出動態(tài)代理時,還很難想象它有多大的實際用途,現(xiàn)在我們終于發(fā)現(xiàn)動態(tài)代理是實現(xiàn)AOP的絕好底層技術(shù)。JDK的動態(tài)代理主要涉及到j(luò)ava.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中InvocationHandler是一個接口,可以通過實現(xiàn)該接口定義橫切邏輯,在并通過反射機制調(diào)用目標(biāo)類的代碼,動態(tài)將橫切邏輯和業(yè)務(wù)邏輯編織在一起。而Proxy為InvocationHandler實現(xiàn)類動態(tài)創(chuàng)建一個符合某一接口的代理實例。這樣講一定很抽象,我們馬上著手動用Proxy和InvocationHandler這兩個魔法戒對上一節(jié)中的性能監(jiān)視代碼進行AOP式的改造。首先,我們從業(yè)務(wù)類ForumServiceImpl中刪除性能監(jiān)視的橫切代碼,使ForumServiceImpl只負(fù)責(zé)具體的業(yè)務(wù)邏輯,如所示:代碼清單5ForumServiceImpl:移除性能監(jiān)視橫切代碼xy;publicclassForumServiceImplimplementsForumService{publicvoidremoveTopic(inttopicId){①System.out.println("模擬刪除Topic記錄:"+topicId);try{Thread.currentThread().sleep(20);}catch(Exceptione){thrownewRuntimeException(e);}②}publicvoidremoveForum(intforumId){①System.out.println("模擬刪除Forum記錄:"+forumId);try{Thread.currentThread().sleep(40);}catch(Exceptione){thrownewRuntimeException(e);}②}}在代碼清單5中的①和②處,原來的性能監(jiān)視代碼被移除了,我們只保留了真正的業(yè)務(wù)邏輯。從業(yè)務(wù)類中移除的橫切代碼當(dāng)然還得找到一個寄居之所,InvocationHandler就是橫切代碼的家園樂土,我們將性能監(jiān)視的代碼安置在PerformaceHandler中,如代碼清單6所示:代碼清單6PerformaceHxy;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;publicclassPerformaceHandlerimplementsInvocationHandler{privateObjecttarget;publicPerformaceHandler(Objecttarget){//①target為目標(biāo)的業(yè)務(wù)類this.target=target;}publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{PerformanceMonitor.begin(target.getClass().getName()+"."+method.getName());Objectbj=method.invoke(target,args);//②通過反射方法調(diào)用目標(biāo)業(yè)務(wù)類的業(yè)務(wù)方法PerformanceMonitor.end();returnobj;}}粗體部分的代碼為性能監(jiān)視的橫切代碼,我們發(fā)現(xiàn),橫切代碼只出現(xiàn)一次,而不是原來那樣星灑各處。大家注意②處的method.invoke(),該語句通過反射的機制調(diào)用目標(biāo)對象的方法,這樣InvocationHandler的invoke(Objectproxy,Methodmethod,Object[]args)方法就將橫切代碼和目標(biāo)業(yè)務(wù)類代碼編織到一起了,所以我們可以將InvocationHandler看成是業(yè)務(wù)邏輯和橫切邏輯的編織器。下面,我們對這段代碼做進一步的說明。首先,我們實現(xiàn)InvocationHandler接口,該接口定義了一個invoke(Objectproxy,Methodmethod,Object[]args)的方法,proxy是代理實例,一般不會用到;method是代理實例上的方法,通過它可以發(fā)起對目標(biāo)類的反射調(diào)用;args是通過代理類傳入的方法參數(shù),在反射調(diào)用時使用。此外,我們在構(gòu)造函數(shù)里通過target傳入真實的目標(biāo)對象,如①處所示,在接口方法invoke(Objectproxy,Methodmethod,Object[]args)里,將目標(biāo)類實例傳給method.invoke()方法,通過反射調(diào)用目標(biāo)類方法,如②所示。下面,我們通過Proxy結(jié)合PerformaceHandler創(chuàng)建ForumService接口的代理實例,如代碼清單7所示:代碼清單7TestForumService:創(chuàng)建代理實例xy;importjava.lang.reflect.Proxy;publicclassTestForumService{publicstaticvoidmain(String[]args){ForumServicetarget=newForumServiceImpl();//①目標(biāo)業(yè)務(wù)類//②將目標(biāo)業(yè)務(wù)類和橫切代碼編織到一起PerformaceHandlerhandler=newPerformaceHandler(target);//③為編織了目標(biāo)業(yè)務(wù)類邏輯和性能監(jiān)視橫切邏輯的handler創(chuàng)建代理類ForumServiceproxy=(ForumService)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);//④操作代理實例proxy.removeForum(10);proxy.removeTopic(1012);}}上面的代碼完成了業(yè)務(wù)類代碼和橫切代碼編織和接口代理實例生成的工作,其中在②處,我們將ForumService實例編織為一個包含性能監(jiān)視邏輯的PerformaceHandler實例,然后在③處,通過Proxy的靜態(tài)方法newProxylnstance()為融合了業(yè)務(wù)類邏輯和性能監(jiān)視邏輯的handler創(chuàng)建一個ForumService接口的代理實例,該方法的第一個入?yún)轭惣虞d器,第二個入?yún)閯?chuàng)建的代理實例所要實現(xiàn)的一組接口,第三個參數(shù)是整合了業(yè)務(wù)邏輯和橫切邏輯的編織器對象。按照③處的設(shè)置方式,這個代理實例就實現(xiàn)了目標(biāo)業(yè)務(wù)類的所有接口,也即ForumServicelmpl的ForumService接口。這樣,我們就可以按照調(diào)用ForumService接口的實例相同的方式調(diào)用代理實例,如④所示。運行以上的代碼,輸出以下的信息:beginmonitor...模擬刪除Forum記錄:10xy.ForumServiceImpl.removeForum花費47毫秒。beginmonitor...模擬刪除Topic記錄:1012xy.ForumServiceImpl.removeTopic花費26毫秒。我們發(fā)現(xiàn),程序的運行效果和直接在業(yè)務(wù)類中編寫性能監(jiān)視邏輯的效果一致,但是在這里,原來分散的橫切邏輯代碼已經(jīng)被我們抽取到PerformaceHandler中。當(dāng)其它業(yè)務(wù)類(如UserService、SystemService等)的業(yè)務(wù)方法也需要使用性能監(jiān)視時,我們只要按照以上的方式,分別為它們創(chuàng)建代理對象就可以了。下面,我們用時序圖描述調(diào)用關(guān)系,進一步代理實例的本質(zhì),如

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論