官术网_书友最值得收藏!

3.4.1 活用切點表達式

Spring AOP的一大特色在于為開發人員提供了非常靈活的切點機制。Spring在編譯期間處理切入點,并嘗試進行優化匹配。然而,檢查代碼中的匹配規則將是一個代價高昂的過程。因此,為了獲得最佳性能,我們需要仔細考慮想要實現的目標,并盡可能縮小搜索或匹配條件的范圍。

我們在3.1.2節中已經看到過一個切點表達式,如代碼清單3-21所示。

代碼清單3-21 切點表達式代碼

@Pointcut("execution(* com.springboot.aop.service.AccountService.doAccountTransaction(..))")
public void doAccountTransaction() {}

這里的execution()代表的就是表達式的主體,它的基本語法如代碼清單3-22所示,其中“?”部分表示可選項,可以為空。

代碼清單3-22 execution()基本語法

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)

這個語法看似復雜,但是我們逐個分解所有的模式,它們其實就是描述了一個方法的特征。

  • modifiers-pattern:表示方法的修飾符。
  • ret-type-pattern:表示方法的返回值。
  • declaring-type-pattern:表示方法所在的類的路徑。
  • name-pattern:表示方法名。
  • param-pattern:表示方法的參數。
  • throws-pattern:表示方法拋出的異常。

這些模式的作用就是完成切點的匹配。在各個模式中,可以使用“*”來表示匹配所有選項。Spring AOP還為開發人員提供了一組非常有用的描述符來簡化切點表達式的使用過程。例如,args描述符表示方法的參數屬于一個特定的類;within描述符表示方法屬于一個特定的類;target描述符表示方法所屬的類等。關于這些描述符的具體使用方法,可以參考Spring AOP的官方文檔:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core

為了獲得良好的性能,在設計切點表達式時,至少應該包含方法和類型模式。這并不是說如果只使用方法或類型模式中的一種,匹配就會不生效,而是因為類型模式的匹配過程非常快,它通過快速選擇無法進一步處理的連接點來縮小搜索空間。

同時,建議在空方法上聲明切點,并通過空方法名引用這些切點。我們在3.1.2節中定義的doAccountTransaction()方法就是一個很好的空方法。基于這種定義,針對需要對切點表達式進行任何更改的場景,只需要修改一個位置即可。

另外一項最佳實踐在于盡量聲明小的切點,并把它們組合起來構建復雜的切點。代碼清單3-23展示了定義小切點并將它們連接起來的代碼示例。

代碼清單3-23 定義并連接小切點代碼示例

@Pointcut("execution(public * *(..))")
private void anyPublicMethod() {}

@Pointcut("execution(* com.springboot.aop.service.AccountService.doAccountTransaction(..))")
public void doAccountTransaction() {}

@Pointcut("anyPublicMethod() && doAccountTransaction()")
private void transactionOperation() {}

這里的transactionOperation()就是由anyPublicMethod()和doAccountTransaction()這兩個切點組合而成的。在日常開發過程中,我們可以根據需要定義各種粒度的切點,并把它們靈活地進行組合。

主站蜘蛛池模板: 九江市| 措美县| 四川省| 海安县| 琼结县| 盘山县| 桑植县| 桃园市| 长海县| 邵武市| 剑川县| 和政县| 灵山县| 得荣县| 科技| 连城县| 福泉市| 镇康县| 清徐县| 浦城县| 金湖县| 论坛| 同德县| 城口县| 项城市| 绍兴市| 固原市| 郁南县| 临海市| 湄潭县| 碌曲县| 台前县| 景宁| 临漳县| 舞钢市| 城市| 孟津县| 类乌齐县| 宝应县| 兴安县| 塔城市|