一篇瞭解什麼是Spring AOP

AOP概述

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

AOP與OOP字面意思相近,但其實二者徹底是面向不一樣領域的設計思想。實際項目中咱們一般將面向對象理解爲一個靜態過程(例如一個系統有多少個模塊,一個模塊有哪些對象,對象有哪些屬性),面向切面的運行期代理方式,理解爲一個動態過程,能夠在對象運行時動態織入一些擴展功能或控制對象執行。spring

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所示:

說明:咱們能夠簡單的將機場的一個安檢口理解爲鏈接點,多個安檢口爲切入點,安全檢查過程當作是通知。總之,概念很晦澀難懂,多作例子,作完就會清晰。先能夠按白話去理解。app

AOP實現步驟

公式:AOP=(切面)=通知方法(5種)+切入點表達式(4種)spa

通知方法

1.@before通知------->在執行目標方法以前執行
2.@after通知------->在執行目標方法以後執行
3.@afterReturning通知------->不管何時程序執行完成以後都要執行的通知
4.@afterThrowing通知------->在目標方法執行以後報錯時執行
(上述四大類型通知,不能控制目標方法是否執行。通常用來記錄程序的執行狀態。通常應用與監控的操做。(不改變程序運行的軌跡)
5.@around通知-------> 在目標方法執行先後執行
(環繞通知可控制目標方法是否執行,控制程序的執行的軌跡.net

切入點表達式

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通知");
}
}


本文分享自微信公衆號 - 願天堂沒有BUG(ma214617)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。代理

相關文章
相關標籤/搜索