Spring AOP 不再怕了!

什麼是AOP?

AOP(Aspect-Oriented Programming:面向切面編程)能夠將那些與業務的邏輯無關 ,但是需要被業務模塊所使用到的代碼邏輯或責任 (如日誌管理、權限控制、事務管理)封裝起來,從而減少代碼的冗餘量,降低模塊間的耦合度,有利於未來的可擴展性和可維護性

簡單來說,AOP就是可以讓你少寫點經常寫的代碼~ 讓你可以專注於業務邏輯,AOP會根據你的指示去幫你做那些你懶得做的重複工作

或許你可以給面試官舉個例子:歌星都有好多助理,歌星最重要的一件事就是唱歌,其他事他不用關注,比如唱歌前可能需要和其他人談合作,還要佈置場地,唱歌后還要收錢等等,這些統統交給他對應的助理去做。

也許哪一天,這個歌星做慈善,免費唱歌了,不收錢了,那麼就可以把收錢這個助力給辭退了。這就是
AOP,每個人各司其職,靈活組合,達到一種可配置的、可插拔的程序結構。AOP 的實現原理就是代理模式。

在程序中也是如此,通過代理,可以詳細控制訪問某個或者某類對象的方法,在調用這個方法前做前置處理,調用這個方法後做後置處理。

簡單瞭解下AOP的一些概念

引用- 已失效

1.通知(Advice)

就是你想要的功能,也就是上面說的 安全,事物,日誌等。你給先定義好把,然後在想用的地方用一下。

2.連接點(JoinPoint)

這個更好解釋了,就是spring允許你使用通知的地方,那可真就多了,基本每個方法的前,後(兩者都有也行),或拋出異常時都可以是連接點,spring只支持方法連接點.其他如aspectJ還可以讓你在構造器或屬性注入時都行,不過那不是咱關注的,只要記住,和方法有關的前前後後(拋出異常),都是連接點。

3.切入點(Pointcut)

上面說的連接點的基礎上,來定義切入點,你的一個類裏,有15個方法,那就有幾十個連接點了對把,但是你並不想在所有方法附近都使用通知(使用叫織入,以後再說),你只想讓其中的幾個,在調用這幾個方法之前,之後或者拋出異常時乾點什麼,那麼就用切點來定義這幾個方法,讓切點來篩選連接點,選中那幾個你想要的方法。

4.切面(Aspect)

切面是通知和切入點的結合。現在發現了吧,沒連接點什麼事情,連接點就是爲了讓你好理解切點,搞出來的,明白這個概念就行了。通知說明了幹什麼和什麼時候幹(什麼時候通過方法名中的before,after,around等就能知道),而切入點說明了在哪幹(指定到底是哪個方法),這就是一個完整的切面定義。

5.引入(introduction)

允許我們向現有的類添加新方法屬性。這不就是把切面(也就是新方法屬性:通知定義的)用到目標類中嗎

6.目標(target)

引入中所提到的目標類,也就是要被通知的對象,也就是真正的業務邏輯,他可以在毫不知情的情況下,被咱們織入切面。而自己專注於業務本身的邏輯。

7.代理(proxy)

AOP框架創建的對象,代理就是目標對象的加強。Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基於接口,後者基於子類

8.織入(weaving)

把切面應用到目標對象來創建新的代理對象的過程。有3種方式,spring採用的是運行時織入,生成字節碼,再加載到虛擬機中,JDKProxy是利用反射原理,Cglib使用了ASM原理

AOP有哪些實現方式?

  1. 靜態代理,使用 AOP 框架提供的命令進行編譯,從而在編譯階段就可生成 AOP 代理類,因此也稱爲編譯時增強
  2. 動態代理 ,在運行時在內存中“臨時”生成 AOP 動態代理類,因此也被稱爲運行時增強

Spring中有哪些不同的通知類型

摘自

通知(advice)是你在你的程序中想要應用在其他模塊中的橫切關注點的實現。Advice主要有以下5種類型:

  • 前置通知(Before Advice): 在連接點之前執行的Advice,不過除非它拋出異常,否則沒有能力中斷執行流。使用 @Before 註解使用這個Advice。
  • 返回之後通知(After Retuning Advice): 在連接點正常結束之後執行的Advice。例如,如果一個方法沒有拋出異常正常返回。通過 @AfterReturning 關注使用它。
  • 拋出(異常)後執行通知(After Throwing Advice): 如果一個方法通過拋出異常來退出的話,這個Advice就會被執行。通用 @AfterThrowing 註解來使用。
  • 後置通知(After Advice): 無論連接點是通過什麼方式退出的(正常返回或者拋出異常)都會執行在結束後執行這些Advice。通過 @After 註解使用。
  • 圍繞通知(Around Advice): 圍繞連接點執行的Advice,就你一個方法調用。這是最強大的Advice。通過 @Around 註解使用。

Spring的AOP基於什麼實現?

動態代理,本質上就是反射。當要代理的目標對象實現了某個接口時,Spring AOP會使用JDKProxy去創建代理對象,而對於沒有實現接口的對象,Spring AOP 會使用Cglib去生成一個目標代理對象的子類來進行代理

CGLIB 創建的動態代理對象比 JDK 創建的動態代理對象的性能更高,但是 CGLIB 創建代理對象時所花費的時間卻比 JDK 多得多。所以對於單例的對象,因爲無需頻繁創建對象,用 CGLIB 合適,反之使用JDK方式要更爲合適一些。同時由於 CGLIB 由於是採用動態創建子類的方法,對於final修飾的方法無法進行代理。

什麼是代理模式?

代理模式的核心作用就是通過代理,控制對對象的訪問。它的設計思路是:定義一個抽象角色,讓代理角色和真實角色分別去實現它。

真實角色:實現抽象角色,定義真實角色所要實現的業務邏輯,供代理角色調用。它只關注真正的業務邏輯,比如歌星唱歌。

代理角色:實現抽象角色,是真實角色的代理,通過真實角色的業務邏輯方法來實現抽象方法,並在前後可以附加自己的操作,比如談合同,佈置場地,收錢等等。

這就是代理模式的設計思路。代理模式分爲靜態代理和動態代理。靜態代理是我們自己創建一個代理類,而動態代理是程序自動幫我們生成一個代理

Spring AOP 和 AspectJ AOP 區別

Spring AOP 是運行時增強,而AspectJ AOP是編譯時增強,Spring AOP是基於代理的,而AspectJ AOP是基於字節碼操作。AspectJ AOP相對來說更強大,Spring AOP更簡單,在切面少的情況下,使用AOP更清晰,但是切面多的情況下,應該使用AspectJ AOP,它在性能上更好

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章