1. 程式人生 > 實用技巧 >SpringAop的核心概念和使用

SpringAop的核心概念和使用

AOP中的核心概念

Pointcut(切入點)

一個專案中有很多類,每個類中有很多個方法。這麼多個方法中,如何定位到需要增強功能的方法呢?靠的是切點

Aspect(切面)

  • 切面由切點和增強組成。

  • 切面=切入點+增強

  • 切面=切入點+方位資訊+橫切邏輯

  • 切面=連線點+橫切邏輯

JoinPoint(連線點)

橫切程式執行的特定位置,比如類中某個方法呼叫前、呼叫後,方法丟擲異常後等,這些程式碼中的特定點就稱為“連線點”。

Target(目標物件)

增強邏輯的目標類。比如未新增任何事務控制的AccountServiceImplNoTcf類

Weaving(織入)

織入是將增強邏輯/橫切邏輯新增到目標類具體連線點上的過程,AOP像一臺織布機,將目標類、增強或者引介通過AOP(其實就是動態代理技術)這臺織布機天衣無縫地編織到一起。

Proxy(代理)

一個類被AOP織入增強後,就產出了一個代理類,它是融合了原類和增強邏輯的代理類。

Advice(通知/增強)

  • 增強的第一層意思就是你的橫切邏輯程式碼(增強邏輯程式碼)

  • 在Spring中,增強除了用於描述橫切邏輯外,包含一層意思就是橫切邏輯執行的方位資訊。剛剛說了切點只能定位到方法,在進一步使用方位資訊就可以定位到我們感興趣的連線點了(方法呼叫前、方法呼叫後還是方法丟擲異常時等)。

Maven座標

<!--
aop的jar包支援--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.12.RELEASE</version> </dependency> <!--aop 依賴支援--> <dependency> <groupId>org.aspectj</groupId
> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency>
格式:
execution(
[modifiers-pattern] //修飾符匹配 可省略
ret-type-pattern //返回值匹配
[declaring-type-pattern](paraname) //類路徑+方法名匹配+引數
[throws-pattern] //異常型別匹配
)
  • [modifiers-pattern]:修飾符匹配,例如public等修飾符列表中的修飾符。
  • ret-type-pattern:返回值匹配可為 * 或 void 或 具體返回值的全限定類名。必填
  • [declaring-type-pattern](paraname):格式 包名.類名.方法名(引數)
    • 沒有引數則為空不填 methName()。
    • 有具體引數需要寫具體引數的全限定類名
    • 一個引數可以使用 methName(*)
    • 若干參數使用 methName(..)
    • 若引數是lang包下資料型別,則省略全限定包名直接寫資料型別
  • [throws-pattern]:方法異常資訊

現在來看看幾個例子

1)com.spring.service.UserServiceImpl包下的saveAll()方法,無返回值,修飾符public
execution(public void com.spring.service.UserServiceImpl.saveAll())
2)省略修飾符,com.spring.service.UserServiceImpl包下的deleteUser方法,引數為Integer 無返回值
execution(void com.spring.service.UserServiceImpl.deleteUser(Integer))
3)省略修飾符,com.spring.service.UserServiceImpl包下的updateUser方法,引數為User 返回值User
execution(com.spring.domain.User com.spring.service.UserServiceImpl.updateUser(com.spring.domain.User)
4)所有引數型別,所有包(有幾層包寫幾個*.)類下的方法
execution(* *.*.*.UserServiceImpl.updateUser(com.spring.domain.User))
5)所有引數型別, ..表示當前包及其子包下所有 類的 所有方法,且此方法只有一個所有滿足引數型別的方法
execution(* com..*.*(*))
6)所有引數累心,所有包下所有方法,且滿足有參和無參,滿足多個引數
execution(* *..*.*(..))
execution(* *(..)) 效果相同