## 10.1、概念 - AOP(Aspect Oriented Programming)是一種設計思想,是軟體設計領域中的面向切麵編程 - AOP是面向對象編程(OOP)的一種補充和完善,OOP是縱向繼承機制,AOP是橫向抽取機制 - AOP能通過預編譯方式和運行期動態代理方式,實現在不修改源代碼 ...
10.1、概念
-
AOP(Aspect Oriented Programming)是一種設計思想,是軟體設計領域中的面向切麵編程
-
AOP是面向對象編程(OOP)的一種補充和完善,OOP是縱向繼承機制,AOP是橫向抽取機制
-
AOP能通過預編譯方式和運行期動態代理方式,實現在不修改源代碼的情況下動態地為程式添加統一的附加功能
10.2、術語
10.2.1、橫切關註點
橫切關註點是從目標方法中抽取出來的非核心業務代碼,一個目標方法中可以有多個橫切關註點
public int add(int i, int j) {
//輸出日誌屬於非核心業務,這是該目標方法的第1個橫切關註點
System.out.println("[日誌] add 方法開始了,參數是:" + i + "," + j);
int result = i + j;
System.out.println("方法內部 result = " + result);
//輸出日誌屬於非核心業務,這是該目標方法的第2個橫切關註點
System.out.println("[日誌] add 方法結束了,結果是:" + result);
return result;
}
10.2.2、通知
非核心業務代碼在目標方法中叫橫切關註點,其被抽取封裝到一個類(切麵類)的方法中,這樣的方法就是通知方法
通知方法一共有五種類型:
-
前置通知:在被代理的目標方法前執行
-
返回通知:在被代理的目標方法成功結束後執行(壽終正寢)
-
異常通知:在被代理的目標方法異常結束後執行(死於非命)
-
後置通知:在被代理的目標方法最終結束後執行(蓋棺定論)
-
環繞通知:包括上面四種通知對應的所有位置
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
//前置通知增強位置:在調用目標對象執行功能之前,加入額外的操作
System.out.println("[日誌] "+method.getName()+" 方法開始了,參數是:" + Arrays.toString(args));
//調用目標對象實現的核心邏輯
result = method.invoke(target, args);
//返回通知增強位置:在調用目標對象執行功能之後,加入額外的操作)
System.out.println("[日誌] "+method.getName()+" 方法結束了,結果是:" + result);
} catch (Exception e) {
//異常通知增強位置:在調用目標對象執行功能發生異常時,加入額外的操作
System.out.println("[日誌] "+method.getName()+",異常:"+e.getMessage());
} finally {
//後置通知增強位置:在調用目標對象執行功能完畢時,加入額外的操作
System.out.println("[日誌] "+method.getName()+",方法執行完畢");
}
//保證代理對象和目標對象的返回值一致
return result;
}
10.2.3、切麵
切麵是封裝通知方法(橫切關註點)的類,也叫切麵類
10.2.4、目標
目標是被代理的(目標)對象,也就是要進行功能增強的對象,也可以說是要被抽取非核心業務代碼的對象
10.2.5、代理
代理是對目標對象進行功能增強的(代理)對象,這個(代理)對象會由AOP通過代理模式自動創建
10.2.6、連接點
連接點是抽取橫切關註點的位置
10.2.7、切入點
切入點是一個表達式,可以定位出連接點,從而實現把切麵類中的通知方法安插到該位置
10.3、作用
-
簡化代碼:把方法中固定位置的重覆代碼抽取出來,讓被抽取非核心業務代碼的方法更專註於自己的核心功能,從而提高內聚性
-
代碼增強:把特定的功能封裝到切麵類中,哪裡有需要就往哪裡安插,被安插了切麵類特定功能的方法就被切麵給增強了