1. 程式人生 > >使用aop建立鬆散耦合(分析日誌程式)

使用aop建立鬆散耦合(分析日誌程式)

 日誌,是每個系統都不可缺少的。但是,又不是必要的業務需求。
        但用於日誌記錄的程式碼和主要用於其它職責的程式碼纏繞在一起。根據所解決的問題的複雜程度和作用域的不同,所引起的混亂可大可小。更改一個應用程式的日誌記錄策略可能涉及數百次編輯 ― 即使可行,這是個令人頭疼的任務。
         考慮一下以下程式碼:
清單 1. 日誌呼叫手工插入到每個方法中                 可能在不同的方法中都存在這樣的程式碼。這就造成程式碼的無限擴張,同時修改也變得非常困難。
       使用aop後,更改的程式碼為:
清單 2. 自動應用於每個方法的記錄日誌呼叫
所有的日誌維護都集中於AutoLog方面。

要理解 Pointcut,必需知道 join point

是什麼。join point 表示在程式執行中明確定義的點。AspectJ 中典型的 join point 包括方法呼叫、對類成員的訪問以及異常處理程式塊的執行。join point 可以包含其它 join point。例如,一個方法呼叫可能在它返回之前引起其它方法呼叫。那麼,Pointcut 就是一種語言構造,這種構造根據已定義的標準挑選一組 join point。示例中的第一個 Pointcut 稱為 publicMethods ,選擇 org.apache.cactus 包中的所有公用(public)方法的執行。 execution 是一個原始的 Pointcut(就象 int 是一種原始的 Java 型別)。它選擇與其括號中定義的方法說明匹配的任何方法的執行。方法說明允許包含萬用字元;示例中的一個方法說明包含了幾個萬用字元。第二個名為 logObjectCalls
的 Pointcut 選擇了 Logger 類中的所有方法的執行。第三個 Pointcut loggableCalls ,通過使用 && ! 合併了前兩個 Pointcut,這意味著它選擇了除 Logger 類中的公用方法以外, org.apache.cactus 中所有的公用方法。(記錄 log 方法將導致無限遞迴。)

既然 Aspect 已經定義了它應該記錄的點,它使用 Advice 來完成實際的日誌記錄。Advice 是在 join point 之前、之後或周圍執行的程式碼。相對於 Pointcut 來定義 Advice,說類似於“在想要記錄的每個方法呼叫之後執行這些程式碼”這樣的話。因此 Advice 如下:


Advice 使用 Logger 類,其入口和出口方法類似於下列程式碼:


在示例中,傳遞到記錄器的 String 是從 thisJoinPoint 派生的,這是一個特殊的反射物件,它允許訪問 join point 執行所處的執行時上下文。在 Cactus 實際使用的 Aspect 中,Advice 使用這種物件來檢索傳遞到每個記錄的方法呼叫中的方法引數。當日志記錄 Aspect 應用於程式碼時,方法呼叫的結果如下: