AOP是spring框架中重要的一環,全稱:Aspect Orient Programming,AOP是一種設計思想,意爲面向切面編程,它是面向對象編程(OOP)的一種補充和完善.它以經過預編譯方式和運行期動態代理方式兩種方式實如今不修改源代碼的狀況下給程序動態統一添加額外功能的一種技術.spring
二者的區別能夠理解爲:
oop是靜態固定的,有多少模塊多少對象,怎麼執行都是運行前寫好的;
aop是動態擴展的,能夠在對象運行時去假如一些擴展的功能或是控制對象執行某些功能.編程
項目中通常有核心業務與非核心業務,而非核心業務通常經過特定方式切入系統-->通常就是藉助於aop來實現.緩存
aop主要基於ocp(開閉原則)--對擴展開放,對修改關閉--簡單來講就是添加功能時,不能改變原有核心業務代碼,只能在其上添加.app
aop能夠實現,如:日誌處理/事務處理/緩存處理等等.框架
AOP底層基於代理機制實現功能擴展,有兩種實現方式:
1) 假如目標對象(被代理對象)實現接口,則底層能夠採用JDK動態代理機制爲目標對象建立代理對象(目標類和代理類會實現共同接口
2) 假如目標對象(被代理對象)沒有實現接口,則底層能夠採用CGLIB代理機制爲目標對象建立代理對象(默認建立的代理類會繼承目標對象類型)oop
Spring boot2.x之後的版本中AOP如今默認使用的CGLIB代理,假如須要使用JDK動態代理能夠在配置文件(applicatiion.properties)中進行以下配置:spa
spring.aop.proxy-target-class=false
1) 切面(aspect): 橫切面對象,通常爲一個具體類對象(能夠藉助@Aspect聲明)---AOP對象
2) 通知(Advice):在切面的某個特定鏈接點上執行的動做(擴展功能),例如around,before,after等---AOP方法
3) 鏈接點(joinpoint):程序執行過程當中某個特定的點,通常指被攔截到的的方法---目標方法
4) 切入點(pointcut):對多個鏈接點(Joinpoint)一種定義,通常能夠理解爲多個鏈接點的集合---目標方法集合設計
@Aspect 註解描述的類爲spring容器的一個切面對象類(此類型中封裝切入點與通知方法)代理
@Pointcut 註解用於描述切入點(在那些點上執行拓展業務)日誌
bean(bean類型名字):爲一種切入點表達式(這個表達式中定義了那些bean對象的方法要進行功能拓展)
例如:bean(sysUserServiceImpl)表示名字爲sysUserServiceImpl的bean對象中全部方法的集合爲切入點,也就是說sysUserServiceImpl對象中任意方法執行時都要進行功能擴展
@Around 註解描述的方法爲一個通知方法(服務增益方法),此方法內部能夠作服務增益(拓展業務)
@Around 註解內部要指定切入點表達式,在此切入點表達式對應的切入點方法上作功能擴展
@param jp 表示鏈接點,是動態肯定的,用於封裝正在執行的切入點方法信息
@return 目標方法的執行結果
@throws Throwable 通知方法執行過程當中出現的異常
ProceedingJoinPoint類爲一個鏈接點類型,此類型的對象用於封裝要執行的目標方法相關的一些信息。只能用於@Around註解描述的方法參數
//執行目標方法 Object result = jp.proceed();//最終會調用目標方法(中間可能會其餘通知方法)
切面通知共有五種:
@Before/@AfterReturning/@AfterThrowing/@After/@Around(優先級最高)
注意:切面並非全部通知都要使用,使用什麼通知由業務決定.
五個通知的執行順序以下:
@Around-->@Before-->目標方法-->@Around-->@After-->@AfterReturning(正常狀況)/@AfterThrowing(異常狀況)
1) bean:用於匹配指定bean對象的全部方法
bean(bean對象名)
bean表達式內部的對象是由spring容器管理的一個bean對象,表達式內部的名字應該是spring容器中某個bean的name
3) within:用於匹配指定包下全部類內的全部方法
within(包名+類名)--不經常使用
5) execution:用於按指定語法規則匹配到具體方法
execution(返回值類型 包名.類名.方法名(參數列表))--不經常使用
7) @annotation:用於匹配指定註解修飾的方法
@annotation(註解全類名) 匹配有此註解描述的方法
咱們須要本身定義註解,當使用這個註解修飾的類就是目標對象
bean/within表達式通常應用於類級別,實現粗粒度的切入點定義--經常使用bean
execution/@annotation表達式應用於方法級別,實現細粒度的切入點表達式定義--經常使用@annotation
當多個切面做用於同一個目標對象方法時,這些切面會構建成一個切面鏈,切面的優先級須要藉助@Order註解進行描述,數字越小優先級越高,默認優先級比較低.