?
? ????? PHP ??? ???? ??? ?? ??
當(dāng)你確定切面是實(shí)現(xiàn)一個(gè)給定需求的最佳方法時(shí),你如何選擇是使用Spring AOP還是AspectJ,以及選擇 Aspect語言(代碼)風(fēng)格、@AspectJ聲明風(fēng)格或XML風(fēng)格?這個(gè)決定會(huì)受到多個(gè)因素的影響,包括應(yīng)用的需求、 開發(fā)工具和小組對AOP的精通程度。
做能起作用的最簡單的事。Spring AOP比完全使用AspectJ更加簡單, 因?yàn)樗恍枰階spectJ的編譯器/織入器到你開發(fā)和構(gòu)建過程中。 如果你僅僅需要在Spring bean上通知執(zhí)行操作,那么Spring AOP是合適的選擇。 如果你需要通知domain對象或其它沒有在Spring容器中管理的任意對象,那么你需要使用AspectJ。 如果你想通知除了簡單的方法執(zhí)行之外的連接點(diǎn)(如:調(diào)用連接點(diǎn)、字段get或set的連接點(diǎn)等等), 也需要使用AspectJ。
當(dāng)使用AspectJ時(shí),你可以選擇使用AspectJ語言(也稱為“代碼風(fēng)格”)或@AspectJ注解風(fēng)格。 很顯然,如果你用的不是Java 5+那么結(jié)論是你只能使用代碼風(fēng)格。 如果切面在你的設(shè)計(jì)中扮演一個(gè)很大的角色,并且你能在Eclipse中使用AspectJ Development Tools (AJDT), 那么首選AspectJ語言 :- 因?yàn)樵撜Z言專門被設(shè)計(jì)用來編寫切面,所以會(huì)更清晰、更簡單。如果你沒有使用 Eclipse,或者在你的應(yīng)用中只有很少的切面并沒有作為一個(gè)主要的角色,你或許應(yīng)該考慮使用@AspectJ風(fēng)格 并在你的IDE中附加一個(gè)普通的Java編輯器,并且在你的構(gòu)建腳本中增加切面織入(鏈接)的段落。
如果你選擇使用Spring AOP,那么你可以選擇@AspectJ或者XML風(fēng)格。顯然如果你不是運(yùn)行 在Java 5上,XML風(fēng)格是最佳選擇。對于使用Java 5的項(xiàng)目,需要考慮多方面的折衷。
XML風(fēng)格對現(xiàn)有的Spring用戶來說更加習(xí)慣。它可以使用在任何Java級別中 (參考連接點(diǎn)表達(dá)式內(nèi)部的命名連接點(diǎn),雖然它也需要Java 5+) 并且通過純粹的POJO來支持。當(dāng)使用AOP作為工具來配置企業(yè)服務(wù)時(shí)XML會(huì)是一個(gè)很好的選擇。 (一個(gè)好的例子是當(dāng)你認(rèn)為連接點(diǎn)表達(dá)式是你的配置中的一部分時(shí),你可能想單獨(dú)更改它) 對于XML風(fēng)格,從你的配置中可以清晰的表明在系統(tǒng)中存在那些切面。
XML風(fēng)格有兩個(gè)缺點(diǎn)。第一是它不能完全將需求實(shí)現(xiàn)的地方封裝到一個(gè)位置。 DRY原則中說系統(tǒng)中的每一項(xiàng)知識都必須具有單一、無歧義、權(quán)威的表示。 當(dāng)使用XML風(fēng)格時(shí),如何實(shí)現(xiàn)一個(gè)需求的知識被分割到支撐類的聲明中以及XML配置文件中。 當(dāng)使用@AspectJ風(fēng)格時(shí)就只有一個(gè)單獨(dú)的模塊 -切面- 信息被封裝了起來。 第二是XML風(fēng)格同@AspectJ風(fēng)格所能表達(dá)的內(nèi)容相比有更多的限制:僅僅支持"singleton"切面實(shí)例模型, 并且不能在XML中組合命名連接點(diǎn)的聲明。例如,在@AspectJ風(fēng)格中我們可以編寫如下的內(nèi)容:
@Pointcut(execution(* get*())) public void propertyAccess() {} @Pointcut(execution(org.xyz.Account+ *(..)) public void operationReturningAnAccount() {} @Pointcut(propertyAccess() && operationReturningAnAccount()) public void accountPropertyAccess() {}
在XML風(fēng)格中能聲明開頭的兩個(gè)連接點(diǎn):
<aop:pointcut id="propertyAccess" expression="execution(* get*())"/> <aop:pointcut id="operationReturningAnAccount" expression="execution(org.xyz.Account+ *(..))"/>
但是不能通過組合這些來定義accountPropertyAccess
連接點(diǎn)
@AspectJ風(fēng)格支持其它的實(shí)例模型以及更豐富的連接點(diǎn)組合。它具有將切面保持為一個(gè)模塊單元的優(yōu)點(diǎn)。 還有一個(gè)優(yōu)點(diǎn)就是@AspectJ切面能被Spring AOP和AspectJ兩者都理解 - 所以如果稍后你認(rèn)為你需要AspectJ的能力去實(shí)現(xiàn)附加的需求,那么你非常容易遷移到基于AspectJ的途徑。 總而言之,我們更喜歡@AspectJ風(fēng)格只要你有切面去做超出簡單的“配置”企業(yè)服務(wù)之外的事情。