Dashboard > OpenSource Project > ... > Spring > 入門 40 - AOP概念
OpenSource Project Log In   View a printable version of the current page.
入門 40 - AOP概念
Added by cheetah, last edited by Forth on Aug 13, 2005  (view change)
Labels: 
(None)

  AOP全名Aspect-Oriented Programming,我們先來看看XXX-Oriented的意義,通常翻譯「XXX導向」,也就是以XXX為中心,例如中文中「客戶導向」就是以客戶為中心,而「物件導向」(OOP:Object-Oriented Programming)就是以物件為中心的程式設計。

  自然的,Aspect-Oriented Programming,就是「Aspect導向程式設計」,也就是以Aspect為中心的程式設計,但什麼是Aspect?中文直譯通常是「方面」,但這個名詞容易使人混淆。

  牛津字典中的英英解釋對Aspect是:particular part or feature of sth being considerd.

  所以Aspect在英文中不只有「方面」的意思,還有部份(part)的意思。中文中稱「就這個方面來說」,通常指的是「就這個角度來說」或「就這個方向來說」,這個解釋不適用於AOP中的Aspect。如果英文中說from this aspect of sth,除了可以翻譯為上面兩句的意義之外,還可以翻作「就這個部份來說」。

  以我們的前一個主題中的記錄(log)動作插入至HelloSpeaker物件的hello()中為例,我們說「就記錄這個部份」是不屬於HelloSpeaker職責的,它被硬生生切入HelloSpeaker中,英文中我們可以說:The logging aspect of the "hello" method doesn't belong to the job of HelloSpeaker.

  所以以整個方法的執行流程來說,如果執行流程是縱向的,則記錄這個動作硬生生的「橫切」入其中,這個橫切入的部份我們就稱之為Aspect,它是橫切關注點(crosscutting concern,一個concern可以像是權限檢查、事務等等)的模組化,將那些散落在物件中各處的程式碼聚集起來。

  所以Aspect要用中文表達的話,適切一些的名詞該是「橫切面」或「切面」。AOP關注於Aspect,將這些Aspect視作中心進行設計,使其中從職責被混淆的物件中分離出來,除了使原物件的職責更清楚之外,被分離出來的Aspect也可以設計的通用化,可運用於不同的場合。

  來看事務管理這個Aspect如何在動態代理下被抽取出來,下面是一個簡單的概念,基本上是在Handler中先啟動事務,執行存儲層動作,方法執行成功則提交(commit),失敗則回滾(rollback):

  代碼:

TransactionHandler.java
public class TransactionHandler implements InvocationHandler { 
    private Object delegate; 

    public Object bind(Object obj) { 
        this.delegate = obj; 
        return Proxy.new ProxyInstance(.., .., ..); 
    } 
    public Object invoke(Object proxy, Method method, Object[] args) { 
        Object result = null; 

        ..... 

        YourTransaction transaction = null; 
        try { 
            transaction = yourMethodForGettingTransaction(); 

            result = method.invoke(delegate, args); 

            transaction.commit(); 
        } 
        catch(YourException e) { 
            if(transaction != null) { 
                try { 
                    transaction.rollback(); 
                } 
                catch(Exception e) {} 
            } 
        } 

        .... 

        return result; 
    } 
}

  在AOP中,有好幾個關鍵的概念,然而其中更主要的是:PointCut、Advice與Advisor。這些術語並不是很直觀,我們配合我們上一個主題的HelloSpeaker來說明會比較容易理解。

  PointCut是JointPoint的集合,JointPoint是指Aspect加入的階段點,例如某個方法被調用,某個成員被存取(Spring不支援),或是某個例外被丟出,以我們前一個主題的HelloSpeaker為例,hello()方法就是一個JointPoint。PointCut為JointPoint的集合,意味著多個方法或例外丟出可以使用同一個處理建議(Advice)。

  Advice是在JointPoint上所要調用的處理建議(在JointPoint上所採取的動作,許多AOP框架通常以interceptor來實作Advice,之後會介紹),例如記錄、事務處理、權限檢查等。

  Advice類型(advice type)有Around、Before、Throws、After returning。這些Advice類型會分別在以下的時機被調用:在JointPoint前後、JointPoint前、JointPoint丟出例外時、JointPoint執行完畢後。

  就我們上一個例子來說,我們在hello()這個JointPoint上會調用Around Advice,即我們的LogHandler。事務管理調用的Advice類型也是屬於Around Advice,即上面的TransactionHandler,調用的JointPoint可能是某個DAO物件的saveXXX()方法。

  Advisor將PointCut與Advice組合在一起,我們前一個主題中的HelloSpeaker例子很簡單,故而沒有使用到Advisor,之後會介紹到Advisor。

  補充:動態代理是比較常見的AOP實作策略,在《Expert One-on-One J2EE Development WIthout EJB》 Rod Johnson、Juergen Hoeller中的第八章中有提到,AOP的實作有五個主要的策略:

  • Dynamic Proxies
  • Dynamic Byte Code Generation
  • Java Code Generation
  • Use of a Custom Class Loader
  • Language Extensions

  在該章中也作了不少對AOP的探討,以及現行幾個主流的AOP實作,像是Spring中的AOP、JBoss中的AOP與AspectJ等的比較,有興趣的可以去看看。

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.1.5a Build:#411 Mar 16, 2006) - Bug/feature request - Contact Administrators