首先經過一個例子來看一下AOP能夠幹什麼,在一個支付系統中,須要作日誌的記錄,在通常狀況下,咱們可使用一個LogUtils的工具類用來記錄支付開始日誌以及支付結果日誌: 正則表達式
支付部分,定義IPayService接口並定義支付方法「pay」,並定義了兩個實現:「PointPayService」表示積分支付,「RMBPayService」表示人民幣支付;而且在每一個支付實現中支付邏輯和記錄日誌: 編程
可是若是對積分支付方式添加統計功能,好比在支付時記錄下用戶總積分數、當前消費的積分數,那咱們該如何作呢?直接修改源代碼添加日誌記錄,這徹底違背了面向對象最重要的原則之一:開閉原則(對擴展開放,對修改關閉)? 緩存
更好的解決方案:在咱們的支付組件中因爲使用了日誌組件,即日誌模塊橫切於支付組件,在傳統程序設計中很難將日誌組件分離出來,即不耦合咱們的支付組件;所以面向方面編程AOP就誕生了,它能分離咱們的組件,使組件徹底不耦合: 框架
1)採用面向方面編程後,咱們的支付組件代碼中再也不有日誌組件的任何東西; 模塊化
2)全部日誌相關的邏輯提取到一個切面中,AOP實現者會在合適的時候將日誌功能織入到咱們的支付組件中去,從而徹底解耦支付組件和日誌組件。
工具
在進行OOP開發時,都是基於對組件(好比類)進行開發,而後對組件進行組合,OOP最大問題就是沒法解耦組件進行開發,而AOP就是爲了克服這個問題而出現的,它來進行這種耦合的分離。 性能
AOP爲開發者提供一種進行橫切關注點(好比日誌關注點橫切了支付關注點)分離並織入的機制,把橫切關注點分離,而後經過某種技術織入到系統中,從而無耦合的完成了咱們的功能。 spa
AOP主要用於橫切關注點分離和織入,所以須要理解橫切關注點和織入: 設計
關注點:能夠認爲是所關注的任何東西,好比上邊的支付組件; 代理
關注點分離:將問題細化從而單獨部分,便可以理解爲不可再分割的組件,如上邊的日誌組件和支付組件;
橫切關注點:一個組件沒法完成須要的功能,須要其餘組件協做完成,如日誌組件橫切於支付組件;
織入:橫切關注點分離後,須要經過某種技術將橫切關注點融合到系統中從而完成須要的功能,所以須要織入,織入可能在編譯期、加載期、運行期等進行。
橫切關注點可能包含不少,好比非業務的:日誌、事務處理、緩存、性能統計、權限控制等等這些非業務的基礎功能;還多是業務的:如某個業務組件橫切於多個模塊。
在進行AOP開發前,先熟悉幾個概念:
鏈接點(Jointpoint):表示須要在程序中插入橫切關注點的擴展點,鏈接點多是類初始化、方法執行、方法調用、字段調用或處理異常等等,Spring只支持方法執行鏈接點,在AOP中表示爲「在哪裏幹」;
切入點(Pointcut):選擇一組相關鏈接點的模式,便可以認爲鏈接點的集合,Spring支持perl5正則表達式和AspectJ切入點模式,Spring默認使用AspectJ語法,在AOP中表示爲「在哪裏乾的集合」;
通知(Advice):在鏈接點上執行的行爲,通知提供了在AOP中須要在切入點所選擇的鏈接點處進行擴展示有行爲的手段;包括前置通知(before advice)、後置通知(after advice)、環繞通知(around advice),異常通知(exception advice),在Spring中經過代理模式實現AOP,並經過攔截器模式以環繞鏈接點的攔截器鏈織入通知;在AOP中表示爲「幹什麼」;
方面/切面(Aspect):橫切關注點的模塊化,好比上邊提到的日誌組件。能夠認爲是通知、引入和切入點的組合;在Spring中可使用Schema和@AspectJ方式進行組織實現;在AOP中表示爲「在哪乾和幹什麼集合」;
目標對象(Target Object):須要被織入橫切關注點的對象,即該對象是切入點選擇的對象,須要被通知的對象,從而也可稱爲「被通知對象」;因爲Spring AOP 經過代理模式實現,從而這個對象永遠是被代理對象,在AOP中表示爲「對誰幹」;
AOP代理(AOP Proxy):AOP框架使用代理模式建立的對象,從而實如今鏈接點處插入通知(即應用切面),就是經過代理來對目標對象應用切面。在Spring中,AOP代理能夠用JDK動態代理或CGLIB代理實現,而經過攔截器模型應用切面。
織入(Weaving):織入是一個過程,是將切面應用到目標對象從而建立出AOP代理對象的過程,織入能夠在編譯期、類裝載期、運行期進行。
在AOP中,經過切入點選擇目標對象的鏈接點,而後在目標對象的相應鏈接點處織入通知,而切入點和通知就是切面(橫切關注點),而在目標對象鏈接點處應用切面的實現方式是經過AOP代理對象。
通知類型:前置通知(Before Advice):在切入點選擇的鏈接點處的方法以前執行的通知,該通知不影響正常程序執行流程(除非該通知拋出異常,該異常將中斷當前方法鏈的執行而返回)。
後置通知(After Advice): 在切入點選擇的鏈接點處的方法以後執行的通知,包括以下類型的後置通知:
環繞通知(Around Advices):環繞着在切入點選擇的鏈接點處的方法所執行的通知,環繞通知能夠在方法調用以前和以後自定義任何行爲,而且能夠決定是否執行鏈接點處的方法、替換返回值、拋出異常等等。