Spring AOP
單獨講概念,我覺得挺難理解的,至少對于我是這樣,哈哈哈,像背八股文一樣,尤其是剛學(xué),沒有實際開發(fā)經(jīng)驗和業(yè)務(wù)場景的小白。我也是前段時間求職復(fù)習(xí),才知道了落下挺多的,通過復(fù)習(xí)和最近工作中有實際的業(yè)務(wù)場景去使用才懂。(底層原理是忘了,到時候再更新,哈哈)。寫個帖子加深一下印象。
場景:對3個/n個excel模板下載增加sheet頁,提供數(shù)據(jù)給客戶填寫參考。在3個service層(策略模式)中,都有相同的權(quán)限校驗和查詢相同的數(shù)據(jù),我把重復(fù)的代碼,和主業(yè)務(wù)不相關(guān)的代碼(權(quán)限校驗,公司歷史遺留問題了)抽出來,通過切面切入。
下面是舉例代碼:(實際代碼有保密,貼不了)
結(jié)合MVC三層架構(gòu)寫的(先學(xué)了MVC好理解一點),沒像一些教程中單獨用spring,xml配置方式和全注解方式去用AOP
寫一個自定義注解,放方法上,標記該方法要進行增強

切面:

在方法上使用注解:

controller:

結(jié)果:

結(jié)合上面說的3個sercice層中的方法,另外兩個方法加上這個注解就行了。
總結(jié):減少重復(fù)代碼,實現(xiàn)代碼的復(fù)用和解耦,提高代碼的可維護性和可擴展性。比如這些場景:日志記錄、事務(wù)管理、權(quán)限控制、接口限流、接口冪等等
下面講概念
概念:
AOP(Aspect Oriented Programming)即面向切面編程,AOP 是 OOP(面向?qū)ο缶幊蹋┑囊环N延續(xù),二者互補,并不對立。
AOP 的目的是將橫切關(guān)注點(如日志記錄、事務(wù)管理、權(quán)限控制、接口限流、接口冪等等)從核心業(yè)務(wù)邏輯中分離出來,通過動態(tài)代理、字節(jié)碼操作等技術(shù),實現(xiàn)代碼的復(fù)用和解耦,提高代碼的可維護性和可擴展性。
術(shù)語:
- 橫切關(guān)注點(cross-cutting concerns) :多個類或?qū)ο笾械墓残袨椋ㄈ缛罩居涗洝⑹聞?wù)管理、權(quán)限控制、接口限流、接口冪等等)。
- 切面(Aspect):對橫切關(guān)注點進行封裝的類,一個切面是一個類。切面可以定義多個通知,用來實現(xiàn)具體的功能。
- 連接點(JoinPoint):連接點是方法調(diào)用或者方法執(zhí)行時的某個特定時刻(如方法調(diào)用、異常拋出等)。
- 通知(Advice):通知就是切面在某個連接點要執(zhí)行的操作。通知有五種類型,分別是前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、異常通知(AfterThrowing)和環(huán)繞通知(Around)。前四種通知都是在目標方法的前后執(zhí)行,而環(huán)繞通知可以控制目標方法的執(zhí)行過程。
- 切點(Pointcut):一個切點是一個表達式,它用來匹配哪些連接點需要被切面所增強。切點可以通過注解、正則表達式、邏輯運算等方式來定義。比如
execution(* com.xyz.service..*(..))匹配com.xyz.service包及其子包下的類或接口。 - 織入(Weaving):織入是將切面和目標對象連接起來的過程,也就是將通知應(yīng)用到切點匹配的連接點上。常見的織入時機有兩種,分別是編譯期織入(Compile-Time Weaving 如:AspectJ)和運行期織入(Runtime Weaving 如:AspectJ、Spring AOP)。

AOP常見通知:
- Before(前置通知):目標對象的方法調(diào)用之前觸發(fā),比如上面代碼的@Before注解
- After (后置通知):目標對象的方法調(diào)用之后觸發(fā)
- AfterReturning(返回通知):目標對象的方法調(diào)用完成,在返回結(jié)果值之后觸發(fā)
- AfterThrowing(異常通知):目標對象的方法運行中拋出 / 觸發(fā)異常后觸發(fā)。AfterReturning 和 AfterThrowing 兩者互斥。如果方法調(diào)用成功無異常,則會有返回值;如果方法拋出了異常,則不會有返回值。
- Around (環(huán)繞通知):編程式控制目標對象的方法調(diào)用。環(huán)繞通知是所有通知類型中可操作范圍最大的一種,因為它可以直接拿到目標對象,以及要執(zhí)行的方法,所以環(huán)繞通知可以任意的在目標對象的方法調(diào)用前后搞事,甚至不調(diào)用目標對象的方法
AOP實現(xiàn)方式:
AOP 的常見實現(xiàn)方式有動態(tài)代理、字節(jié)碼操作等方式。
Spring AOP 就是基于動態(tài)代理的,如果要代理的對象,實現(xiàn)了某個接口,那么 Spring AOP 會使用 JDK Proxy,去創(chuàng)建代理對象,而對于沒有實現(xiàn)接口的對象,就無法使用 JDK Proxy 去進行代理了,這時候 Spring AOP 會使用 Cglib 生成一個被代理對象的子類來作為代理。
也可以使用 AspectJ !Spring AOP 已經(jīng)集成了 AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了。
Spring AOP 屬于運行時增強,而 AspectJ 是編譯時增強。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字節(jié)碼操作(Bytecode Manipulation)。
Spring AOP 已經(jīng)集成了 AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加強大,但是 Spring AOP 相對來說更簡單,
如果我們的切面比較少,那么兩者性能差異不大。但是,當切面太多的話,最好選擇 AspectJ ,它比 Spring AOP 快很多。
參考:https://javaguide.cn/system-design/framework/spring/spring-knowledge-and-questions-summary.html

浙公網(wǎng)安備 33010602011771號