AOP(Aspect Oriented Programming),意思是面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP基於IoC基礎,是對OOP(Object Oriented Programming,面向對象)的延續。同時,AOP實際是GOF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,提升代碼的靈活性和可擴展性,AOP能夠說也是這種目標的一種實現。正則表達式
AOP將應用系統分爲兩部分,核心業務邏輯(Core business concerns)及橫向的通用邏輯,也就是所謂的方面Crosscutting enterprise concerns,例如,全部大中型應用都要涉及到的持久化管理(Persistent)、事務管理(Transaction Management)、安全管理(Security)、日誌管理(Logging)和調試管理(Debugging)等。編程
AOP、OOP在字面上雖然很是相似,但倒是面向不一樣領域的兩種設計思想。OOP(面向對象編程)針對業務處理過程的實體及其屬性和行爲進行抽象封裝,以得到更加清晰高效的邏輯單元劃分。設計模式
而AOP則是針對業務處理過程當中的切面進行提取,它所面對的是處理過程當中的某個步驟或階段,以得到邏輯過程當中各部分之間低耦合性的隔離效果。這兩種設計思想在目標上有着本質的差別。安全
上面的陳述可能過於理論化,舉個簡單的例子,對於「僱員」這樣一個業務實體進行封裝,天然是OOP/OOD的任務,咱們能夠爲其創建一個「Employee」類,並將「僱員」相關的屬性和行爲封裝其中。而用AOP設計思想對「僱員」進行封裝將無從談起。框架
一樣,對於「權限檢查」這一動做片段進行劃分,則是AOP的目標領域。而經過OOD/OOP對一個動做進行封裝,則有點不三不四。模塊化
換而言之,OOD/OOP面向名詞領域,AOP面向動詞領域。spa
要想真正的瞭解AOP,首先要了解幾個重要的基本概念:設計
一、切面(Aspect):對橫切性關注點的模塊化,其實就是共有功能的實現。如日誌切面、權限切面等。代理
二、鏈接點(JoinPoint):就是程序在運行過程當中可以插入切面的地點。例如,方法調用、異常拋出或字段修改等,但Spring只支持調試
方法級的鏈接點。
三、通知(Advice):在切面的某個特定的鏈接點(Joinpoint)上執行的動做。通知有各類類型,其中包
括"around"、"before」和"after"等通知。許多AOP框架,包括Spring,都是以攔截器作通知模型, 並維護一個以鏈接點爲中心的攔截
器鏈。
四、切入點(Pointcut):用於定義通知(Advice)應該切入到哪些鏈接點(JoinPoint)上。不一樣的通知一般須要切入到不一樣的鏈接點上,這種精準的匹配是由切入點的正則表達式來定義的。
五、目標對象(Target):就是那些即將切入切面的對象,也就是那些被通知的對象。
六、代理對象(Proxy):將通知應用到目標對象以後被動態建立的對象。能夠簡單地理解爲,代理對象的功能等於目標對象的核心
業務邏輯功能加上共有功能。代理對象對於使用者而言是透明的,是程序運行過程當中的產物。
七、織入(Weaving):將切面應用到目標對象從而建立一個新的代理對象的過程。這個過程能夠發生在編譯期、類裝載期及運行
期,固然不一樣的發生點有着不一樣的前提條件。譬如發生在編譯期的話,就要求有一個支持這種AOP實現的特殊編譯器;發生在類裝
載期,就要求有一個支持AOP實現的特殊類裝載器;只有發生在運行期,則可直接經過Java語言的反射機制與動態代理機制來動態
實現。
咱們用一張圖將這些概念串聯起來,具體的代碼在後面的博文中:
爲了符合現實的各類需求,通知類型提供了5種,能夠對目標方法進行全方位處理;
一、Before advice:在某鏈接點(JoinPoint)以前執行的通知,但這個通知不能阻止鏈接點前的執行。
ApplicationContext中在<aop:aspect>裏面使用<aop:before>元素進行聲明。
二、After advice:當某鏈接點退出的時候執行的通知(不管是正常返回仍是異常退出)。
ApplicationContext中在<aop:aspect>裏面使用<aop:after>元素進行聲明。
三、After returnadvice:在某鏈接點正常完成後執行的通知,不包括拋出異常的狀況。
ApplicationContext中在<aop:aspect>裏面使用<aop:after-returning>元素進行聲明。
四、Around advice:包圍一個鏈接點的通知,相似Web中Servlet規範中的Filter的doFilter方法。能夠在方法的調用先後完成自定義的
行爲,也能夠選擇不執行。
ApplicationContext中在<aop:aspect>裏面使用<aop:around>元素進行聲明。
五、Afterthrowing advice:在方法拋出異常退出時執行的通知。
ApplicationContext中在<aop:aspect>裏面使用<aop:after-throwing>元素進行聲明。
AOP支持2種代理,Jdk的動態代理和CGLIB實現機制。兩者有什麼區別呢:
Jdk基於接口實現:JDK動態代理對實現了接口的類進行代理。
CGLIB基於繼承:CGLIB代理能夠對類代理,主要對指定的類生成一個子類,由於是繼承,因此目標類最好不要使用final聲明。
一般狀況下,鼓勵使用jdk代理,由於業務通常都會抽象出一個接口,並且不用引入新的東西。若是是遺留的系統,之前沒有實現接口,那麼只能使用CGLIB。
Spring AOP配置有兩種風格:
XML風格 = 採用聲明形式實現Spring AOP
AspectJ風格 = 採用註解形式實現Spring AOP
下篇博文,會分別使用兩種風格實踐一下Spring AOP,敬請關注。