??? 面向方面編程(AOP)是一種新的規范,允許你達到以前面對對象方法無法達到的組織和分層你的應用程序的方法. 方面允許你很明顯的把功能性的東西粘合起來,所以你就可以很方便的為程序設計很多的層。AOP可以攔截所有JAVA程序中的事件觸發。
??? 什么是AOP?
??? 一個方面(aspect)就是一個共有的特性,具有此代表性的有:橫向分離的方法,類,對象層次或者實體對象模型。它們看起來應該是組合在一起的,但是在AOP里面你不用像以前面對對象(OO)那樣來組織它們了。
??? 在傳統JAVA中要加入計算時間的代碼到你的應用中,你必須按以下方式:
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);
? }
?}
}
??? 我們可以列舉這里面存在的幾個問題:
??? 1。如果你要在每個你的方法中都加入這樣的代理,無疑是十分糟糕的,特別是有try/catch這樣的語句。
??? 2。這里有很多代碼都不是你真實需要用到的,這樣就使你的程序代碼十分臃腫,讀起來也十分困難。而且你不得不把你的代碼放在try里面......
???
??? 3。如果你要擴展這段代碼,我們可以遇見到那將是十分困難的工作。
??? 所以可見,這樣的代碼是十分難于維護,擴展和繼承的,因為在這里面有很多東西分散了你對你這段代碼真正要實現的東西的注意力。而且這只不過是一段最簡單的例子,在真正的OOP中是很難實現對以上代碼更好的表現方法的。
??? 面對方面編程可以分離你的這些功能性,可以讓你增加行為來圍繞你的功能代碼。例如上面的,AOP就可以使在執行你自己的代碼前你可以控制執行其它的功能。
??? 所有實現AOP的框架都有兩種方式:組裝關注點 和 a programmatic construct(編程實現)
??? JBOSS的一個橫向切入關注點
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. }
??? 真正實現的功能代碼是在8行調用了,這就是實現了組裝關注點,使之成為了一個方面。這讓我們在以后擴展實際功能的時候就十分方便了,只需要去修改具體的實現方法,而不用去關心其它關注點了。
??? JBOOS中具體應用這個方面
??? 需要定義一個切入點(pointcuts),全部通過政則表達式來實現。
??? 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定義的一個切入點的方法就是 BankAccountDAO->withdraw(double amount)
??? 4-6定義的是一個通用的,它的切入點是所有的com.mc.billing.下面的類的方法。