簡體   English   中英

Spring AOP 與 AspectJ

[英]Spring AOP vs AspectJ

我的印象是 Spring AOP 最適合用於特定於應用程序的任務,例如安全性、日志記錄、事務等,因為它使用自定義 Java5 注釋作為框架。 然而,AspectJ 似乎更友好的設計模式明智。

任何人都可以強調在 Spring 應用程序中使用 Spring AOP 與 AspectJ 的各種優缺點嗎?

Spring-AOP 優點

  • 它比 AspectJ 更易於使用,因為您不必使用 LTW(加載時編織)或 AspectJ 編譯器。

  • 它使用代理模式和裝飾模式

Spring-AOP 的缺點

  • 這是基於代理的 AOP,所以基本上你只能使用方法執行連接點。
  • 調用同一類中的另一個方法時,不會應用方面。
  • 可能會有一點運行時開銷。
  • Spring-AOP 不能向不是由 Spring 工廠創建的任何內容添加方面

AspectJ 優點

  • 這支持所有連接點。 這意味着你可以做任何事情。
  • 運行時開銷比 Spring AOP 少。

AspectJ 缺點

  • 當心。 檢查您的方面是否僅被編織到您想要編織的東西。
  • 您需要使用 AspectJ Compiler 進行額外的構建過程,或者必須設置 LTW(加載時編織)

除了其他人所說的 - 只是改寫一下, there are two major differences

  1. 一是與編織方式有關。
  2. 另一個連接點定義。

Spring-AOP: dynamic proxy if interface exists or cglib library if direct implementation provided.使用dynamic proxy if interface exists or cglib library if direct implementation provided.概念dynamic proxy if interface exists or cglib library if direct implementation provided.通過代理進行運行時編織dynamic proxy if interface exists or cglib library if direct implementation provided.

AspectJ:如果源代碼可用,則通過AspectJ Java Tools(ajc compiler)編譯時編織或編譯后編織(使用編譯文件)。 此外,可以啟用 Spring 的加載時間編織 - 它需要aspectj定義文件並提供靈活性。

編譯時編織可以提供性能優勢(在某些情況下),並且joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.

附加說明:如果高負載下的性能很重要,您將需要比 Spring AOP 快 9-35 倍的 AspectJ 10ns vs 355ns 聽起來可能不多,但我見過人們使用很多方面。 10K的價值方面。 在這些情況下,您的請求可能涉及數千個方面。 在這種情況下,您將 ms 添加到該請求中。

請參閱基准

彈簧用戶手冊會給出很多信息,直接從馬嘴里說出來。

6.4- 選擇要使用的 AOP 聲明樣式對您來說已經死了,因為它討論了兩者的優缺點。

6.1.2- Spring AOP 功能和目標和章節6.2 - @Aspect 支持6.8 - 在 Spring 應用程序中使用 AspectJ應該特別有趣。

Spring AOP 是 Spring 框架的重要組成部分之一。 在非常基礎的階段,spring 框架是基於 IoC 和 AOP 的。 在 Spring 的官方課程中有一張幻燈片,其中說:

AOP 是框架中最重要的部分之一。

理解 Spring 中 AOP 如何工作的關鍵點是,當您使用 Spring 編寫 Aspect 時,我們通過為您的對象構建代理來檢測框架,如果您的 bean 實現了一個接口,則使用JDKDynamicProxy或如果您的 bean 沒有實現,則通過 CGLIB任何接口。 請記住,如果您使用 3.2 版之前的 Spring,則您的類路徑中必須有 cglib 2.2。 從 Spring 3.2 開始它是無用的,因為 cglib 2.2 包含在核心中。

bean 創建時的框架將創建一個代理來包裝您的對象並添加橫切關注點職責,例如安全性、事務管理、日志記錄等。

以這種方式創建的代理將從切入點表達式開始應用,該切入點表達式檢測框架以決定將創建哪些 bean 和方法作為代理。 建議將比您的代碼承擔更多的責任。 請記住,在此過程中,切入點僅捕獲未聲明為 final 的公共方法。

現在,雖然在 Spring AOP 中,Aspects 的編織將由容器在容器啟動時執行,但在 AspectJ 中,您必須通過字節碼修改對代碼進行后期編譯來執行此操作。 出於這個原因,我認為 Spring 方法比 AspectJ 更簡單、更易於管理。

另一方面,使用 Spring AOP,您不能使用 AOP 的所有功能,因為實現是通過代理完成的,而不是通過修改代碼來完成的。

與在 AspectJ 中一樣,您可以在 SpringAOP 中使用加載時編織。 您可以從 spring 中的此功能中受益,該功能是通過代理和特殊配置、 @EnabledLoadWeaving或在 XML 中實現的。 您可以使用名稱空間作為示例。 但是在 Spring AOP 中,您無法攔截所有情況。 例如,Spring AOP 不支持new命令。

但是,在 Spring AOP 中,您可以通過在 spring 配置 bean 中使用aspectof工廠方法,從 AspectJ 的使用中aspectof

因為 Spring AOP 基本上是從容器創建的代理,所以只能對 spring bean 使用 AOP。 使用 AspectJ 時,您可以在所有 bean 中使用切面。 另一個比較點是調試和代碼行為的可預測性。 使用 spring AOP,這項工作全部由 Java 編譯器執行,方面是為 Spring bean 創建代理的一種非常酷的方式。 在 AspectJ 中,如果您修改代碼,則需要更多的編譯,並且了解方面的編織位置可能會很困難。 即使在 spring 中關閉編織也更簡單:使用 spring,您可以從配置中刪除方面,重新啟動,它就可以工作了。 在 AspectJ 中,您必須重新編譯代碼!

在加載時編織方面,AspectJ 比 Spring 更靈活,因為 Spring 並不支持 AspectJ 的所有選項。 但在我看來,如果您想更改 bean 的創建過程,更好的方法是在工廠中管理自定義登錄,而不是通過加載時編織改變新操作符行為的方面。

希望這張AspectJ和Spring AOP的全景圖能幫助大家了解這兩種葯水的區別

這篇文章也對這個話題有很好的解釋。

Spring AOP 和 AspectJ 有不同的目標。

Spring AOP 旨在提供跨 Spring IoC 的簡單 AOP 實現,以解決程序員面臨的最常見問題。

另一方面,AspectJ 是原始的 AOP 技術,旨在提供完整的 AOP 解決方案。

重要的是要考慮您的方面是否將是關鍵任務以及您的代碼部署在哪里。 Spring AOP 將意味着您依賴加載時編織。 這可能會失敗編織在我的經驗意味着,可能存在記錄錯誤,但不會阻止應用程序而無需方面運行的代碼[我要補充的警告,它可能配置它以這樣的方式,這是不案件; 但我個人並不知道]。 編譯時編織避免了這種情況。

此外,如果您將 AspectJ 與 aspectj-maven-plugin 結合使用,那么您就能夠在 CI 環境中針對您的方面運行單元測試,並確信構建的工件已經過測試和正確編織。 雖然您當然可以編寫 Spring 驅動的單元測試,但您仍然無法保證部署的代碼將是在 LTW 失敗時測試過的代碼。

另一個考慮因素是您是否將應用程序托管在能夠直接監控服務器/應用程序啟動成功或失敗的環境中,或者您的應用程序是否部署在不受您監督的環境中[例如由客戶托管]。 同樣,這將指出編譯時編織的方法。

五年前,我更喜歡 Spring 配置的 AOP,原因很簡單,它更容易使用,而且不太可能占用我的 IDE。 然而,隨着計算能力和可用內存的增加,這已經變得不那么重要了,基於我上面概述的原因,帶有 aspectj-maven-plugin 的 CTW 已成為我工作環境中更好的選擇。

與 AOP 相比,AspectJ 不需要在編譯時增強目標類。 相反,它在運行時為目標類生成一個代理類,它要么實現與目標類相同的接口,要么是目標類的子類。

總之,代理類的實例可以用作目標類的實例。 總的來說,編譯時增強型AOP框架在性能上更有優勢——因為運行時增強型AOP框架每次運行都需要動態增強。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM