使用aop建立鬆散耦合(分析日誌程式)
阿新 • • 發佈:2019-02-13
日誌,是每個系統都不可缺少的。但是,又不是必要的業務需求。
但用於日誌記錄的程式碼和主要用於其它職責的程式碼纏繞在一起。根據所解決的問題的複雜程度和作用域的不同,所引起的混亂可大可小。更改一個應用程式的日誌記錄策略可能涉及數百次編輯 ― 即使可行,這是個令人頭疼的任務。
考慮一下以下程式碼:
清單 1. 日誌呼叫手工插入到每個方法中 可能在不同的方法中都存在這樣的程式碼。這就造成程式碼的無限擴張,同時修改也變得非常困難。
使用aop後,更改的程式碼為:
清單 2. 自動應用於每個方法的記錄日誌呼叫
所有的日誌維護都集中於AutoLog方面。
是什麼。join point 表示在程式執行中明確定義的點。AspectJ 中典型的 join point 包括方法呼叫、對類成員的訪問以及異常處理程式塊的執行。join point 可以包含其它 join point。例如,一個方法呼叫可能在它返回之前引起其它方法呼叫。那麼,Pointcut 就是一種語言構造,這種構造根據已定義的標準挑選一組 join point。示例中的第一個 Pointcut 稱為
但用於日誌記錄的程式碼和主要用於其它職責的程式碼纏繞在一起。根據所解決的問題的複雜程度和作用域的不同,所引起的混亂可大可小。更改一個應用程式的日誌記錄策略可能涉及數百次編輯 ― 即使可行,這是個令人頭疼的任務。
考慮一下以下程式碼:
清單 1. 日誌呼叫手工插入到每個方法中 可能在不同的方法中都存在這樣的程式碼。這就造成程式碼的無限擴張,同時修改也變得非常困難。
使用aop後,更改的程式碼為:
清單 2. 自動應用於每個方法的記錄日誌呼叫
所有的日誌維護都集中於AutoLog方面。
要理解 Pointcut,必需知道 join point
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 應用於程式碼時,方法呼叫的結果如下: