??? 面向方面編程(AOP)是一種新的規(guī)范,允許你達(dá)到以前面對(duì)對(duì)象方法無(wú)法達(dá)到的組織和分層你的應(yīng)用程序的方法. 方面允許你很明顯的把功能性的東西粘合起來(lái),所以你就可以很方便的為程序設(shè)計(jì)很多的層。AOP可以攔截所有JAVA程序中的事件觸發(fā)。
??? 什么是AOP?
??? 一個(gè)方面(aspect)就是一個(gè)共有的特性,具有此代表性的有:橫向分離的方法,類,對(duì)象層次或者實(shí)體對(duì)象模型。它們看起來(lái)應(yīng)該是組合在一起的,但是在AOP里面你不用像以前面對(duì)對(duì)象(OO)那樣來(lái)組織它們了。
??? 在傳統(tǒng)JAVA中要加入計(jì)算時(shí)間的代碼到你的應(yīng)用中,你必須按以下方式:
public class BankAccountDAO{
?public void withdraw(double amount){
? long startTime = System.currentTimeMillis();
? try? {
??? // Actual method body...
? }
? finally? {
??? long endTime = System.currentTimeMillis() - startTime;
??? System.out.println("withdraw took: "?? endTime);
? }
?}
}
??? 我們可以列舉這里面存在的幾個(gè)問(wèn)題:
??? 1。如果你要在每個(gè)你的方法中都加入這樣的代理,無(wú)疑是十分糟糕的,特別是有try/catch這樣的語(yǔ)句。
??? 2。這里有很多代碼都不是你真實(shí)需要用到的,這樣就使你的程序代碼十分臃腫,讀起來(lái)也十分困難。而且你不得不把你的代碼放在try里面......
???
??? 3。如果你要擴(kuò)展這段代碼,我們可以遇見(jiàn)到那將是十分困難的工作。
??? 所以可見(jiàn),這樣的代碼是十分難于維護(hù),擴(kuò)展和繼承的,因?yàn)樵谶@里面有很多東西分散了你對(duì)你這段代碼真正要實(shí)現(xiàn)的東西的注意力。而且這只不過(guò)是一段最簡(jiǎn)單的例子,在真正的OOP中是很難實(shí)現(xiàn)對(duì)以上代碼更好的表現(xiàn)方法的。
??? 面對(duì)方面編程可以分離你的這些功能性,可以讓你增加行為來(lái)圍繞你的功能代碼。例如上面的,AOP就可以使在執(zhí)行你自己的代碼前你可以控制執(zhí)行其它的功能。
??? 所有實(shí)現(xiàn)AOP的框架都有兩種方式:組裝關(guān)注點(diǎn) 和 a programmatic construct(編程實(shí)現(xiàn))
??? JBOSS的一個(gè)橫向切入關(guān)注點(diǎn)
01. public class Metrics implements org.jboss.aop.Interceptor
02. {
03.?? public Object invoke(Invocation invocation) throws Throwable
04.?? {
05.?? long startTime = System.currentTimeMillis();
06.?? try
07.?? {
08.???? return invocation.invokeNext();
09.?? }
10.?? finally
11.?? {
12.???? long endTime = System.currentTimeMillis() - startTime;
13.???? java.lang.reflect.Method m = ((MethodInvocation)invocation).method;
14.???? System.out.println("method "?? m.toString()?? " time: "?? endTime?? "ms");
15.?? }
16.? }
17. }
??? 真正實(shí)現(xiàn)的功能代碼是在8行調(diào)用了,這就是實(shí)現(xiàn)了組裝關(guān)注點(diǎn),使之成為了一個(gè)方面。這讓我們?cè)谝院髷U(kuò)展實(shí)際功能的時(shí)候就十分方便了,只需要去修改具體的實(shí)現(xiàn)方法,而不用去關(guān)心其它關(guān)注點(diǎn)了。
??? JBOOS中具體應(yīng)用這個(gè)方面
??? 需要定義一個(gè)切入點(diǎn)(pointcuts),全部通過(guò)政則表達(dá)式來(lái)實(shí)現(xiàn)。
??? Listing Three: Defining a pointcut in JBoss AOP
1. <bind pointcut="public void com.mc.BankAccountDAO->withdraw(double amount)">
2.???? <interceptor class="com.mc.Metrics"/>
3. </bind >
4. <bind pointcut="* com.mc.billing.*->*(..)">
5.???? <interceptor class="com.mc.Metrics"/>
6. </bind >
??? 1-3定義的一個(gè)切入點(diǎn)的方法就是 BankAccountDAO->withdraw(double amount)
??? 4-6定義的是一個(gè)通用的,它的切入點(diǎn)是所有的com.mc.billing.下面的類的方法。