AOP(Aspect Orient Programming),面向切面編程,是面向?qū)ο缶幊?OOP 的一種補充。面向?qū)ο缶幊淌菑撵o態(tài)角度考慮程序的結(jié)構(gòu),而面向切面編程是從動態(tài)角度考慮程序運行過程。
AOP 底層,就是采用動態(tài)代理模式實現(xiàn)的。采用了兩種代理:JDK 的動態(tài)代理,與 CGLIB 的動態(tài)代理。
AOP 為 Aspect Oriented Programming 的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)。AOP 是 OOP 的延續(xù),是軟件開發(fā)中的一個熱點,也是 Spring 框架中的一個重要內(nèi)容。利用 AOP 可以對業(yè)務(wù)邏輯的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
面向切面編程,就是將交叉業(yè)務(wù)邏輯封裝成切面,利用 AOP 容器的功能將切面織入到主業(yè)務(wù)邏輯中。所謂交叉業(yè)務(wù)邏輯是指,通用的、與主業(yè)務(wù)邏輯無關(guān)的代碼,如安全檢查、事務(wù)、日志、緩存等。
若不使用 AOP,則會出現(xiàn)代碼糾纏,即交叉業(yè)務(wù)邏輯與主業(yè)務(wù)邏輯混合在一起。這樣,會使主業(yè)務(wù)邏輯變的混雜不清。
例如,轉(zhuǎn)賬,在真正轉(zhuǎn)賬業(yè)務(wù)邏輯前后,需要權(quán)限控制、日志記錄、加載事務(wù)、結(jié)束事務(wù)等交叉業(yè)務(wù)邏輯,而這些業(yè)務(wù)邏輯與主業(yè)務(wù)邏輯間并無直接關(guān)系。但,它們的代碼量所占比重能達到總代碼量的一半甚至還多。它們的存在,不僅產(chǎn)生了大量的“冗余”代碼,還大大干擾了主業(yè)務(wù)邏輯---轉(zhuǎn)賬。
● 切面(Aspect)
切面泛指交叉業(yè)務(wù)邏輯。上例中的事務(wù)處理、日志處理就可以理解為切面。常用的切面是通知(Advice)。實際就是對主業(yè)務(wù)邏輯的一種增強。
● 織入(Weaving)
織入是指將切面代碼插入到目標對象的過程。上例中MyInvocationHandler類中的invoke() 方法完成的工作,就可以稱為織入。
● 連接點(JoinPoint)
連接點指可以被切面織入的具體方法。通常業(yè)務(wù)接口中的方法均為連接點。
● 切入點(Pointcut)
切入點指聲明的一個或多個連接點的集合。通過切入點指定一組方法。
被標記為 final 的方法是不能作為連接點與切入點的。因為最終的是不能被修改的,不能被增強的。
● 目標對象(Target)
目標對象指將要被增強的對象。即包含主業(yè)務(wù)邏輯的類的對象。上例中的StudentServiceImpl的對象若被增強,則該類稱為目標類,該類對象稱為目標對象。當然,不被增強,也就無所謂目標不目標了。
● 通知(Advice)
通知是切面的一種實現(xiàn),可以完成簡單織入功能(織入功能就是在這里完成的)。上例中的 MyInvocationHandler 就可以理解為是一種通知。換個角度來說,通知定義了增強代碼切入到目標代碼的時間點,是目標方法執(zhí)行之前執(zhí)行,還是之后執(zhí)行等。通知類型不同,切入時間不同。 切入點定義切入的位置,通知定義切入的時間。