轉(zhuǎn)帖|其它|編輯:郝浩|2009-04-01 10:03:03.000|閱讀 505 次
概述:但是好像并沒有完整的實(shí)現(xiàn)一個(gè)簡(jiǎn)單AOP框架的例子(當(dāng)然我只是簡(jiǎn)單的找了一下,如有遺漏懇請(qǐng)諒解。),正好趁這個(gè)機(jī)會(huì)寫一個(gè)這方面的例子,能夠讓像我這樣的菜鳥對(duì)AOP有更多的了解。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
周末兩天窩在家里,使用Emit做了一個(gè)非常簡(jiǎn)單的AOP框架,當(dāng)做是這幾周學(xué)習(xí)Emit后的一個(gè)實(shí)踐。東西出來了,自然要和大家分享一下,雖然框架做的比較粗糙、簡(jiǎn)單,但是也已經(jīng)能夠看到一點(diǎn)AOP的雛形了,用來自己無聊玩玩還是可以的,當(dāng)然要用到產(chǎn)品中去肯定還需要長(zhǎng)期的完善啦。
說起AOP相信園子里很多高手都研究過,園子里好像也有自己的開源AOP項(xiàng)目,不過我時(shí)間有限沒有細(xì)找,同時(shí)也發(fā)現(xiàn)園子研究AOP理論方面的文章很多,但是好像并沒有完整的實(shí)現(xiàn)一個(gè)簡(jiǎn)單AOP框架的例子(當(dāng)然我只是簡(jiǎn)單的找了一下,如有遺漏懇請(qǐng)諒解。),正好趁這個(gè)機(jī)會(huì)寫一個(gè)這方面的例子,能夠讓像我這樣的菜鳥對(duì)AOP有更多的了解。
有關(guān)AOP的概念介紹,網(wǎng)上有非常多的解釋,我也沒有時(shí)間一一細(xì)看,這里給出百度百科中的解釋:
面向方面編程:Aspect Oriented Programming
AOP是OOP的延續(xù),是Aspect Oriented Programming的縮寫,意思是面向切面編程。可以通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說也是這種目標(biāo)的一種實(shí)現(xiàn)。
舉例:假設(shè)有在一個(gè)應(yīng)用系統(tǒng)中,有一個(gè)共享的數(shù)據(jù)必須被并發(fā)同時(shí)訪問,首先,將這個(gè)數(shù)據(jù)封裝在數(shù)據(jù)對(duì)象中,稱為Data Class,同時(shí),將有多個(gè)訪問類,專門用于在同一時(shí)刻訪問這同一個(gè)數(shù)據(jù)對(duì)象。
為了完成上述并發(fā)訪問同一資源的功能,需要引入鎖Lock的概念,也就是說,某個(gè)時(shí)刻,當(dāng)有一個(gè)訪問類訪問這個(gè)數(shù)據(jù)對(duì)象時(shí),這個(gè)數(shù)據(jù)對(duì)象必須上鎖Locked,用完后就立即解鎖unLocked,再供其它訪問類訪問。
使用傳統(tǒng)的編程習(xí)慣,我們會(huì)創(chuàng)建一個(gè)抽象類,所有的訪問類繼承這個(gè)抽象父類,如下:
abstract class Worker{
abstract void locked();
abstract void accessDataObject();
abstract void unlocked();
}
缺點(diǎn):
accessDataObject()方法需要有“鎖”狀態(tài)之類的相關(guān)代碼。
Java只提供了單繼承,因此具體訪問類只能繼承這個(gè)父類,如果具體訪問類還要繼承其它父類,比如另外一個(gè)如Worker的父類,將無法方便實(shí)現(xiàn)。
重用被打折扣,具體訪問類因?yàn)橐舶?/span>“鎖”狀態(tài)之類的相關(guān)代碼,只能被重用在相關(guān)有“鎖”的場(chǎng)合,重用范圍很窄。
仔細(xì)研究這個(gè)應(yīng)用的“鎖”,它其實(shí)有下列特性:
l “鎖”功能不是具體訪問類的首要或主要功能,訪問類主要功能是訪問數(shù)據(jù)對(duì)象,例如讀取數(shù)據(jù)或更改動(dòng)作。
l “鎖”行為其實(shí)是和具體訪問類的主要功能可以獨(dú)立、區(qū)分開來的。
l “鎖”功能其實(shí)是這個(gè)系統(tǒng)的一個(gè)縱向切面,涉及許多類、許多類的方法。如下圖:
因此,一個(gè)新的程序結(jié)構(gòu)應(yīng)該是關(guān)注系統(tǒng)的縱向切面,例如這個(gè)應(yīng)用的“鎖”功能,這個(gè)新的程序結(jié)構(gòu)就是aspect(方面)
在這個(gè)應(yīng)用中,“鎖”方面(aspect)應(yīng)該有以下職責(zé):
提供一些必備的功能,對(duì)被訪問對(duì)象實(shí)現(xiàn)加鎖或解鎖功能。以保證所有在修改數(shù)據(jù)對(duì)象的操作之前能夠調(diào)用lock()加鎖,在它使用完成后,調(diào)用unlock()解鎖。
AOP應(yīng)用范圍
很明顯,AOP非常適合開發(fā)J2EE容器服務(wù)器,目前JBoss 4.0正是使用AOP框架進(jìn)行開發(fā)。
具體功能如下:
l Authentication 權(quán)限
l Caching 緩存
l Context passing 內(nèi)容傳遞
l Error handling 錯(cuò)誤處理
l Lazy loading 懶加載
l Debugging 調(diào)試
l logging, tracing, profiling and monitoring 記錄跟蹤 優(yōu)化 校準(zhǔn)
l Performance optimization 性能優(yōu)化
l Persistence 持久化
l Resource pooling 資源池
l Synchronization 同步
l Transactions 事務(wù)
AOP有必要嗎
當(dāng)然,上述應(yīng)用范例在沒有使用AOP情況下,也得到了解決,例如JBoss 3.XXX也提供了上述應(yīng)用功能,但是沒有使用AOP。
但是,使用AOP可以讓我們從一個(gè)更高的抽象概念來理解軟件系統(tǒng),AOP也許提供一種有價(jià)值的工具。可以這么說:因?yàn)槭褂?/span>AOP結(jié)構(gòu),現(xiàn)在JBoss 4.0的源碼要比JBoss 3.X容易理解多了,這對(duì)于一個(gè)大型復(fù)雜系統(tǒng)來說是非常重要的。
從另外一個(gè)方面說,好像不是所有的人都需要關(guān)心AOP,它可能是一種架構(gòu)設(shè)計(jì)的選擇,如果選擇J2EE系統(tǒng),AOP關(guān)注的上述通用方面都已經(jīng)被J2EE容器實(shí)現(xiàn)了,J2EE應(yīng)用系統(tǒng)開發(fā)者可能需要更多地關(guān)注行業(yè)應(yīng)用方面aspect。
看了上面的內(nèi)容,相信大家也跟我一樣對(duì)AOP有了一個(gè)大致的了解,接下來就對(duì)我們的AOP框架要實(shí)現(xiàn)的功能進(jìn)行界定。
首先,我們將一個(gè)方法的執(zhí)行分成為如下幾個(gè)部分:
l 調(diào)用前的預(yù)處理:可以包括日志記錄、權(quán)限控制、驗(yàn)證安全性等;
l 真正的方法體調(diào)用;
l 調(diào)用后的處理:可以包括事后的日志記錄、持久化調(diào)用結(jié)果等;
l 套在前面3個(gè)部分外面的異常處理程序。
這樣,我們就把要關(guān)注的切面分成了3類:調(diào)用前處理、調(diào)用后處理以及異常處理。我們通過屬性+接口+配置文件的方式來完成開發(fā)人員對(duì)這些切面的定義及使用。這里先給出一個(gè)客戶端的方法中的使用示例,其它的就等下次再講吧,明天還得早起,得洗洗睡了。
public class Test
{
[Aspect(AspectTypes.PreProcess | AspectTypes.ExceptionHandler)]
public virtual void Test1(string num)
{
Console.WriteLine(Convert.ToInt32(num));
}
[Aspect(AspectTypes.PostProcess | AspectTypes.ExceptionHandler)]
public virtual int Test2(string num)
{
return Convert.ToInt32(num);
}
[Aspect(AspectTypes.ExceptionHandler)]
public virtual int Test3(string num)
{
return Convert.ToInt32(num);
}
}
在具體的使用時(shí),只要按照下面的方法創(chuàng)建一個(gè)動(dòng)態(tài)代理類即可,非常的簡(jiǎn)便,如下:
Test test = DynamicProxyFactory.CreateProxy<Test>(typeof(Test));
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客園