AOP概述
AOP(Aspect Orient Programming)是一種設計思想,是軟體設計領域中的面向切面編程,它是面向物件編程(OOP)的一種補充和完善,它以通過預編譯方式和運行期動態代理方式,實作在不修改源代碼的情況下給程式動態統一添加額外功能的一種技術,如圖-1所示:

AOP與OOP字面意思相近,但其實兩者完全是面向不同領域的設計思想,實際專案中我們通常將面向物件理解為一個靜態程序(例如一個系統有多少個模塊,一個模塊有哪些物件,物件有哪些屬性),面向切面的運行期代理方式,理解為一個動態程序,可以在物件運行時動態織入一些擴展功能或控制物件執行,
AOP 應用場景分析
實際專案中通常會將系統分為兩大部分,一部分是核心業務,一部分是非核業務,在編程實作時我們首先要完成的是核心業務的實作,非核心業務一般是通過特定方式切入到系統中,這種特定方式一般就是借助AOP進行實作,
AOP就是要基于OCP(開閉原則),在不改變原有系統核心業務代碼的基礎上動態添加一些擴展功能并可以"控制"物件的執行,例如AOP應用于專案中的日志處理,事務處理,權限處理,快取處理等等,如圖-2所示:

AOP 應用原理分析
Spring AOP底層基于代理機制實作功能擴展:
1)假如目標物件(被代理物件)實作介面,則底層可以采用JDK動態代理機制為目標物件創建代理物件(目標類和代理類會實作共同介面),
2)假如目標物件(被代理物件)沒有實作介面,則底層可以采用CGLIB代理機制為目標物件創建代理物件(默認創建的代理類會繼承目標物件型別),
Spring AOP 原理分析,如圖-3所示:

AOP 相關術語分析
切面(aspect): 橫切面物件,一般為一個具體類物件(可以借助@Aspect宣告),
通知(Advice):在切面的某個特定連接點上執行的動作(擴展功能),例如around,before,after等,
連接點(joinpoint):程式執行程序中某個特定的點,一般指被攔截到的的方法,
切入點(pointcut):對多個連接點(Joinpoint)一種定義,一般可以理解為多個連接點的集合,
連接點與切入點定義如圖-4所示:

說明:我們可以簡單的將機場的一個安檢口理解為連接點,多個安檢口為切入點,安全檢查程序看成是通知,總之,概念很晦澀難懂,多做例子,做完就會清晰,先可以按白話去理解,
AOP實作步驟
公式:AOP=(切面)=通知方法(5種)+切入點運算式(4種)
通知方法
1.@before通知------->在執行目標方法之前執行
2.@after通知------->在執行目標方法之后執行
3.@afterReturning通知------->在目標方法執行之后報錯時執行
4.@afterThrowing通知------->無論什么時候程式執行完成之后都要執行的通知
(上述四大型別通知,不能控制目標方法是否執行,一般用來記錄程式的執行狀態,一般應用與監控的操作,(不改變程式運行的軌跡)
5.@around通知-------> 在目標方法執行前后執行
(環繞通知可控制目標方法是否執行,控制程式的執行的軌跡
切入點運算式
1.@bean(“beanId”) -------> bean:交給spring容器管理的物件,粒度:粗粒度 按bean匹配 當前bean中的方法都會執行通知
2.@within(“包名.類名”) ------->粒度:粗粒度 可以匹配多個類
3.@execution("回傳值型別 包名.類名.方法名(引數串列)-------> 細粒度:方法引數級別
4.@annotation(“包名.類名”) ------->細粒度:按照注解匹配
package com.jt.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component//交給spring容器管理
public class CacheAOP {
//@Pointcut("bean(itemCatServiceImpl)")
//@Pointcut("within(com.jt.service.ItemCatServiceImpl)")
//@Pointcut("within(com.jt.service.*)")//.*一級包目錄,..*所有子孫后代
@Pointcut("execution(* com.jt.service..*.add*(..))")
public void pointCut(){
}
@Before("pointCut()")
public void before(){
System.out.println("我是before通知");
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229159.html
標籤:java
