javascript
比较Spring AOP和AspectJ
1. 介紹
當(dāng)前有多個(gè)可用的AOP庫,這些庫必須能夠回答許多問題:
- 它與我現(xiàn)有的或新的應(yīng)用程序兼容嗎?
- 在哪里可以實(shí)施AOP?
- 它與我的應(yīng)用程序集成的速度有多快?
- 性能開銷是多少?
在本文中,我們將著眼于回答這些問題,并介紹Spring AOP和AspectJ(這兩種最流行的Java AOP框架)。
2. AOP 概念
在開始之前,讓我們對術(shù)語和核心概念進(jìn)行快速的高層次審查:
- 切面–一種標(biāo)準(zhǔn)代碼/功能,分散在應(yīng)用程序的多個(gè)位置,通常與實(shí)際的業(yè)務(wù)邏輯(例如,事務(wù)管理)不同。每個(gè)方面都專注于特定的跨領(lǐng)域功能
- 連接點(diǎn)–這是程序執(zhí)行過程中的特定點(diǎn),例如方法執(zhí)行,構(gòu)造函數(shù)調(diào)用或字段分配
- 通知–方面在特定聯(lián)接點(diǎn)中采取的操作
- 切入點(diǎn)–與聯(lián)接點(diǎn)匹配的正則表達(dá)式。每當(dāng)任何連接點(diǎn)與切入點(diǎn)匹配時(shí),都會(huì)執(zhí)行與該切入點(diǎn)關(guān)聯(lián)的指定建議
- 編織–將方面與目標(biāo)對象鏈接以創(chuàng)建建議對象的過程
3.Spring AOP 和AspectJ
現(xiàn)在,讓我們從多個(gè)角度討論Spring AOP和AspectJ,例如功能,目標(biāo),編織,內(nèi)部結(jié)構(gòu),連接點(diǎn)和簡單性
3.1 能力和目標(biāo)
簡而言之,Spring AOP和AspectJ具有不同的目標(biāo)。 Spring AOP旨在在Spring IoC上提供一個(gè)簡單的AOP實(shí)現(xiàn),以解決程序員面臨的最常見問題。它不打算用作完整的AOP解決方案-只能應(yīng)用于由Spring容器管理的bean。 另一方面,AspectJ是原始的AOP技術(shù),旨在提供完整的AOP解決方案。它比Spring AOP更強(qiáng)大,但也更復(fù)雜。還值得注意的是,AspectJ可以應(yīng)用于所有域?qū)ο蟆?/p>
3.2 編織
AspectJ和Spring AOP都使用不同類型的編織,這會(huì)影響它們在性能和易用性方面的行為。 AspectJ使用三種不同的編織方式:
有關(guān)AspectJ本身的更多信息,請繼續(xù)閱讀本文。 由于AspectJ使用編譯時(shí)和類加載時(shí)編織,因此Spring AOP使用運(yùn)行時(shí)編織。 通過運(yùn)行時(shí)編織,可以在應(yīng)用程序執(zhí)行期間使用目標(biāo)對象的代理來編織各方面–使用JDK動(dòng)態(tài)代理或CGLIB代理(將在下一部分中進(jìn)行討論):
3.3 內(nèi)部結(jié)構(gòu)與應(yīng)用
Spring AOP是基于代理的AOP框架。這意味著要實(shí)現(xiàn)目標(biāo)對象的各個(gè)方面,它將創(chuàng)建該對象的代理。這可以通過以下兩種方式之一來實(shí)現(xiàn):
我們可以從官方文檔中了解有關(guān)Spring AOP代理機(jī)制的更多信息。 另一方面,AspectJ在運(yùn)行時(shí)不執(zhí)行任何操作,因?yàn)轭愂侵苯佑梅矫婢幾g的。 因此,與Spring AOP不同,它不需要任何設(shè)計(jì)模式。為了將代碼的各個(gè)方面編織起來,它引入了稱為AspectJ編譯器(ajc)的編譯器,通過它我們可以編譯程序,然后通過提供一個(gè)小的(<100K)運(yùn)行時(shí)庫來運(yùn)行它。
3.4 連接點(diǎn)
在3.3節(jié)中,我們展示了Spring AOP基于代理模式。因此,它需要對目標(biāo)Java類進(jìn)行子類化,并相應(yīng)地應(yīng)用跨領(lǐng)域關(guān)注點(diǎn)。 但是它有一個(gè)局限性。我們不能跨“最終”類應(yīng)用跨領(lǐng)域關(guān)注點(diǎn)(或方面),因?yàn)樗鼈儾荒鼙桓采w,因此會(huì)導(dǎo)致運(yùn)行時(shí)異常。 靜態(tài)方法和最終方法也是如此。 Spring方面不能應(yīng)用于它們,因?yàn)樗鼈儾荒鼙桓采w。因此,由于這些限制,Spring AOP僅支持方法執(zhí)行連接點(diǎn)。 但是,AspectJ在運(yùn)行時(shí)之前將橫切關(guān)注點(diǎn)直接編織到實(shí)際代碼中。與Spring AOP不同,它不需要子類化目標(biāo)對象,因此也支持許多其他連接點(diǎn)。以下是受支持的連接點(diǎn)的摘要:
| Method Call | No | Yes |
| Method Execution | Yes | Yes |
| Constructor Call | No | Yes |
| Constructor Execution | No | Yes |
| Static initializer execution | No | Yes |
| Object initialization | No | Yes |
| Field reference | No | Yes |
| Field assignment | No | Yes |
| Handler execution | No | Yes |
| Advice execution | No | Yes |
還值得注意的是,在Spring AOP中,方面未應(yīng)用于同一類中調(diào)用的方法。 顯然,這是因?yàn)楫?dāng)我們在同一類中調(diào)用方法時(shí),便沒有調(diào)用Spring AOP提供的代理方法。如果需要此功能,則必須在不同的bean中定義一個(gè)單獨(dú)的方法,或使用AspectJ。
3.5 簡單
Spring AOP顯然更簡單,因?yàn)樗跇?gòu)建過程之間沒有引入任何額外的編譯器或編織器。它使用運(yùn)行時(shí)編織,因此可以與我們通常的構(gòu)建過程無縫集成。盡管看起來很簡單,但是它僅適用于Spring管理的bean。 但是,要使用AspectJ,我們需要引入AspectJ編譯器(ajc)并重新打包所有庫(除非我們切換到后編譯或加載時(shí)編織)。 當(dāng)然,這比前者要復(fù)雜得多,因?yàn)樗肓薃spectJ Java工具(包括編譯器(ajc),調(diào)試器(ajdb),文檔生成器(ajdoc),程序結(jié)構(gòu)瀏覽器(ajbrowser)),需要與我們的IDE或構(gòu)建工具集成。
3.6 性能
就性能而言,編譯時(shí)編織比運(yùn)行時(shí)編織快得多。 Spring AOP是基于代理的框架,因此在應(yīng)用程序啟動(dòng)時(shí)會(huì)創(chuàng)建代理。此外,每個(gè)方面還有更多方法調(diào)用,這會(huì)對性能產(chǎn)生負(fù)面影響。 另一方面,AspectJ在應(yīng)用程序執(zhí)行之前將各方面編織到主代碼中,因此與Spring AOP不同,沒有額外的運(yùn)行時(shí)開銷。 由于這些原因,基準(zhǔn)測試表明AspectJ幾乎比Spring AOP快8到35倍。
4. 摘要
下表概述了Spring AOP和AspectJ之間的主要區(qū)別:
| Implemented in pure Java-- 用純Java實(shí)現(xiàn) | Implemented using extensions of Java programming language-- 使用Java編程語言的擴(kuò)展實(shí)現(xiàn) |
| No need for separate compilation process-- 無需單獨(dú)的編譯過程 | Needs AspectJ compiler (ajc) unless LTW is set up-- 除非設(shè)置了LTW,否則需要AspectJ編譯器(ajc) |
| Only runtime weaving is available-- 僅需運(yùn)行時(shí)編織 | Runtime weaving is not available. Supports compile-time, post-compile, and load-time Weaving-- 運(yùn)行時(shí)編織不可用。支持編譯時(shí),后編譯和加載時(shí)編織 |
| Less Powerful – only supports method level weaving-- 不足–僅支持方法級編織 | More Powerful – can weave fields, methods, constructors, static initializers, final class/methods, etc…–更強(qiáng)大–可以編織字段,方法,構(gòu)造函數(shù),靜態(tài)初始值設(shè)定項(xiàng),最終類/方法等… |
| Can only be implemented on beans managed by Spring container-- 只能在Spring容器管理的bean上實(shí)現(xiàn) | Can be implemented on all domain objects-- 可以在所有領(lǐng)域?qū)ο笊蠈?shí)施 |
| Supports only method execution pointcuts-- 僅支持方法執(zhí)行切入點(diǎn) | Support all pointcuts-- 支持所有切入點(diǎn) |
| Proxies are created of targeted objects, and aspects are applied on these proxies-- 代理是針對目標(biāo)對象創(chuàng)建的,并且方面已應(yīng)用于這些代理 | Aspects are weaved directly into code before application is executed (before runtime)–在應(yīng)用程序執(zhí)行之前(運(yùn)行時(shí)之前)將方面直接編織到代碼中 |
| Much slower than AspectJ-- 比AspectJ慢得多 | Better Performance-- 更好的性能 |
| Easy to learn and apply-- 易于學(xué)習(xí)和應(yīng)用 | Comparatively more complicated than Spring AOP-- 比Spring AOP復(fù)雜得多 |
5. 選擇正確的框架
如果我們分析本節(jié)中提出的所有論點(diǎn),就會(huì)開始理解,一個(gè)框架根本不比另一個(gè)框架更好。 簡而言之,選擇很大程度上取決于我們的要求:
- 框架:如果應(yīng)用程序未使用Spring框架,那么我們別無選擇,只能放棄使用Spring AOP的想法,因?yàn)樗鼰o法管理Spring容器無法達(dá)到的任何功能。但是,如果我們的應(yīng)用程序是完全使用Spring框架創(chuàng)建的,那么我們可以使用Spring AOP,因?yàn)樗子趯W(xué)習(xí)和應(yīng)用
- 靈活性:鑒于有限的連接點(diǎn)支持,Spring AOP并不是完整的AOP解決方案,但它解決了程序員面臨的最常見問題。盡管如果我們想更深入地挖掘和利用AOP的最大功能,并希望獲得廣泛的可用連接點(diǎn)的支持,那么AspectJ是一個(gè)不錯(cuò)的選擇
- 性能:如果我們使用的方面有限,則性能上將存在微不足道的差異。但是有時(shí)在應(yīng)用程序具有成千上萬個(gè)方面的情況下。在這種情況下,我們不想使用運(yùn)行時(shí)編織,因此最好選擇AspectJ。已知AspectJ比Spring AOP快8到35倍
- 兩者兼有:這兩個(gè)框架彼此完全兼容。我們總是可以盡可能利用Spring AOP,并且仍然使用AspectJ來獲得前者不支持的連接點(diǎn)的支持。
6. 結(jié)論
在本文中,我們在幾個(gè)關(guān)鍵領(lǐng)域分析了Spring AOP和AspectJ。 我們比較了兩種AOP方法的靈活性以及它們與我們的應(yīng)用的適應(yīng)性。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的比较Spring AOP和AspectJ的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++计算-eigen(1)
- 下一篇: CodeBlocks 20.03 配置