選擇使用哪種 AOP 宣告風格
一旦你決定使用切面是實現特定需求的最佳方法,你該如何選擇使用 Spring AOP 還是 AspectJ,以及選擇切面語言(程式碼)風格、@AspectJ 註解風格還是 Spring XML 風格?這些決定受許多因素影響,包括應用需求、開發工具以及團隊對 AOP 的熟悉程度。
Spring AOP 還是完整的 AspectJ?
使用最簡單且可行的方法。Spring AOP 比使用完整的 AspectJ 更簡單,因為它不需要將 AspectJ 編譯器/織入器引入你的開發和構建過程。如果你只需要通知 Spring bean 上操作的執行,Spring AOP 是正確的選擇。如果你需要通知不由 Spring 容器管理的(通常是領域物件之類的)物件,則需要使用 AspectJ。如果你希望通知除簡單方法執行以外的連線點(例如,欄位獲取或設定連線點等),也需要使用 AspectJ。
使用 AspectJ 時,你可以選擇 AspectJ 語言語法(也稱為“程式碼風格”)或 @AspectJ 註解風格。如果切面在你的設計中扮演重要角色,並且你能夠使用 AspectJ Development Tools (AJDT) 的 Eclipse 外掛,那麼 AspectJ 語言語法是首選選項。它更清晰、更簡單,因為該語言是專門為編寫切面而設計的。如果你不使用 Eclipse 或者只有少量切面在應用中不扮演主要角色,你可能需要考慮使用 @AspectJ 風格,堅持在你的 IDE 中進行常規 Java 編譯,並在構建指令碼中新增一個切面織入階段。
Spring AOP 使用 @AspectJ 還是 XML?
如果你選擇使用 Spring AOP,你可以選擇 @AspectJ 或 XML 風格。這裡有一些需要考慮的權衡。
XML 風格對現有的 Spring 使用者可能最熟悉,並且它由純粹的 POJO 支援。當使用 AOP 作為配置企業服務的工具時,XML 是一個不錯的選擇(一個很好的判斷標準是,你是否認為切入點表示式是你配置的一部分,並且你可能希望獨立地修改它)。使用 XML 風格時,從你的配置中可以看出系統中有哪些切面,這一點可以說更清晰。
XML 風格有兩個缺點。首先,它不能在一個地方完全封裝其所解決需求的實現。DRY 原則指出,系統中的任何知識都應該有一個單一、明確、權威的表示。使用 XML 風格時,關於如何實現某個需求的知識被分散在支援 bean 類的宣告和配置檔案中的 XML 中。使用 @AspectJ 風格時,這些資訊被封裝在一個單一模組中:切面。其次,XML 風格在表達能力上比 @AspectJ 風格稍有限制:只支援“單例”切面例項化模型,並且無法組合在 XML 中宣告的命名切入點。例如,在 @AspectJ 風格中,你可以寫如下內容
-
Java
-
Kotlin
@Pointcut("execution(* get*())")
public void propertyAccess() {}
@Pointcut("execution(com.xyz.Account+ *(..))")
public void operationReturningAnAccount() {}
@Pointcut("propertyAccess() && operationReturningAnAccount()")
public void accountPropertyAccess() {}
@Pointcut("execution(* get*())")
fun propertyAccess() {}
@Pointcut("execution(com.xyz.Account+ *(..))")
fun operationReturningAnAccount() {}
@Pointcut("propertyAccess() && operationReturningAnAccount()")
fun accountPropertyAccess() {}
在 XML 風格中,你可以宣告前兩個切入點
<aop:pointcut id="propertyAccess"
expression="execution(* get*())"/>
<aop:pointcut id="operationReturningAnAccount"
expression="execution(com.xyz.Account+ *(..))"/>
XML 方法的缺點在於,你無法透過組合這些定義來定義 accountPropertyAccess
切入點。
@AspectJ 風格支援更多的例項化模型和更豐富的切入點組合。它的優勢在於將切面保持為一個模組化的單元。它還有一個優勢是 @AspectJ 切面可以被 Spring AOP 和 AspectJ 同時理解(並因此被消費)。因此,如果你後來決定需要 AspectJ 的能力來實現附加需求,你可以輕鬆遷移到經典的 AspectJ 配置。總的來說,對於超出簡單企業服務配置的自定義切面,Spring 團隊更偏好 @AspectJ 風格。