第一章:面向切面程式設計-AOP概念和相關術語
“我們聚焦的永遠是我們的目標,我需要喝水,水就是我們的目標,而水的質量好壞不應該讓我喝水這件事情變得複雜,它應該由相關的機構去完成,在我喝水之前”
1、前言
檢測水是否可以飲用是一個很重要的環節,但是並不是我應該重點關注的問題,如果每一次我需要購買水喝,都先拿著水去檢測一遍,是不是讓我們原本要做的事情變得很複雜呢?而且仔細想一下,檢測水質量這件事,是不是可以批量呢?如果有個相關機構在將水售賣前批量去質檢,是不是比我們每個人拿著水去相關單位檢查更有效率呢?
我們專案也有很多業務也和上面一樣的情況,比如安全、事務、日誌等等,這些不是主線的事情與並不應該讓我們原本要做的事情變得複雜。
所以我們相關機構切入到我們的行動中的這種思想就是面向切面的思想。

2、Aop術語

引用Spring實戰第四版的圖片
和大多數技術一樣,Aop已經形成了自己的術語:
通知(advice): 切面也有目標,在Aop中,切面的工作被稱為通知。通知定義了切面是什麼、什麼時候使用。除了描述要完成什麼工作,還描述了什麼時候去完成。
Spring切面可以應用5中型別的通知:
—— 前置通知(Before): 在目標方法被呼叫之前呼叫通知功能
—— 後置通知(After): 在目標方法完成之後呼叫通知,此時不會關心方法的輸出是什麼
—— 返回通知(After-returning): 在目標方法成功執行之後通知
—— 異常通知(After-throwing): 在目標方法丟擲異常後呼叫通知
—— 環繞通知(Around): 通知包裹了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行自定義的行為
例如:@Before("") 這個就是前置通知,before定義了時間,被註解的方法定義了通知的內容
注: aop的實現是基於代理模式去實現的,可以在目標方法的之前、之後、執行操作中丟擲異常等節點加入邏輯
連線點(Join point): 連線點是應用執行過程中能夠插入切面的一個點,這個點可以是呼叫方法時、丟擲異常時、甚至於修改欄位時。這種時機有很多,切面程式碼可以利用這些切入點插入到應用的正常流程中,並新增新的行為。
切點(Poincut): 如果說通知定義了切面是“什麼”(what)、“何時”(when),那麼切點就定義了“何處”(where),我們通常使用明確的類和方法名或是利用正則表示式定義所匹配的類和方法名來指定這些切點。有些Aop框架允許我們建立動態的切點,可以根據執行時的決策來決定是否應用通知
例如:execution(* com.study.pany.bean.aop.Performance.perform(..) 這個就是切點
切面(Aspect): 切面是通知和切點的結合,通知和切點共同定義了切面的全部內容(what、when、where)
例如: Audience 就是切面,被@Aspect修飾
@Component
@Aspect
public class Audience {
@Before("execution(* com.study.pany.bean.aop.Performance.perform(..))")
public void silenceCellPhones(){
System.out.println("Silencing cell phones");
}
}
引入(Instroduction): 引入它允許我們向現有類新增新方法和屬性,可以在不修改現有類的基礎上,讓現有類具有新的行為和狀態
織入(weaving): 織入是把切面應用到目標物件並建立新的代理的過程,切面在指定的連線點被織入到目標物件中。在目標物件的生命週期中有多個連線點可以進行織入:
編譯期: 切面在目標類編譯時被織入,依賴特殊的編譯器
類載入期: 切面在目標類載入到JVM時被織入,依賴類載入器
執行期: 切面在應用執行的某個時刻被織入
3、Spring使用AspectJ註解來宣告通知方法(擴充)
@After 通知方法會在目標方法返回或丟擲異常後呼叫,相當於@AfterReturning + @AfterThrowing
@AfterReturning 通知方法會在目標方法返回之後呼叫
@AfterThrowing 通知方法會在目標方法丟擲異常後呼叫
@Before 通知方法會在目標方法執行之前呼叫
@Around 通知方法會將目標方法封裝起來