在傳統的編寫業務邏輯處理代碼時,咱們一般會習慣性地作幾件事情:日誌記錄、事務控制及 權限控制等,而後纔是編寫核心的業務邏輯處理代碼。當代碼編寫完成回頭再看時,不由發現,揚揚灑灑上百行代碼中,真正用於核心業務邏輯處理才那麼幾行,如 圖6-4所示。方法複方法,類復類,就這樣子帶着迫不得已遺憾地度過了多少個春秋。這倒也罷,假若到了項目的尾聲,忽然決定在權限控制上須要進行大的變更 時,成千上萬個方法又得一一"登門拜訪",痛苦"雪上加霜"。程序員
若是能把圖6-4中衆多方法中的全部共有代碼所有抽取出來,放置到某個地方集中管理,而後在具體運行時,再由容器動態織入這些共有代碼的話,最起碼能夠解決兩個問題:正則表達式
Java EE程序員在編寫具體的業務邏輯處理方法時,只需關心核心的業務邏輯處理,既提升了工做效率,又使代碼變動簡潔優雅。編程
在往後的維護中因爲業務邏輯代碼與共有代碼分開存放,並且共有代碼是集中存放的,所以使維護工做變得簡單輕鬆。spa
面向切面編程AOP技術就是爲解決這個問題而誕生的,切面就是橫切面,如圖6-5所示,表明的是一個廣泛存在的共有功能,例如,日誌切面、權限切面及事務切面等。代理
下面咱們以用戶管理業務邏輯組件UserService的AOP實現過程(見圖6-6)爲例,深度剖析一下AOP技術的實現原理。AOP技術是創建 在Java語言的反射機制與動態代理機制之上的。業務邏輯組件在運行過程當中,AOP容器會動態建立一個代理對象供使用者調用,該代理對象已經按Java EE程序員的意圖將切面成功切入到目標方法的鏈接點上,從而使切面的功能與業務邏輯的功能同時得以執行。從原理上講,調用者直接調用的實際上是AOP容器動 態生成的代理對象,再由代理對象調用目標對象完成原始的業務邏輯處理,而代理對象則已經將切面與業務邏輯方法進行了合成。日誌
現將圖6-6中涉及到的一些概念解釋以下。對象
切面(Aspect):其實就是共有功能的實現。如日誌切面、權限切面、事務切面等。在實際應用中一般是一個存放共有功能實現的普通Java類,之因此能被AOP容器識別成切面,是在配置中指定的。事務
通知(Advice):是切面的具體實現。以目標方法爲參照點,根據放置的地方不一樣,可分爲前置通知(Before)、後置通知 (AfterReturning)、異常通知(AfterThrowing)、最終通知(After)與環繞通知(Around)5種。在實際應用中一般 是切面類中的一個方法,具體屬於哪類通知,一樣是在配置中指定的。ci
鏈接點(Joinpoint):就是程序在運行過程當中可以插入切面的地點。例如,方法調用、異常拋出或字段修改等,但Spring只支持方法級的鏈接點。get
切入點(Pointcut):用於定義通知應該切入到哪些鏈接點上。不一樣的通知一般須要切入到不一樣的鏈接點上,這種精準的匹配是由切入點的正則表達式來定義的。
目標對象(Target):就是那些即將切入切面的對象,也就是那些被通知的對象。這些對象中已經只剩下乾乾淨淨的核心業務邏輯代碼了,全部的共有功能代碼等待AOP容器的切入。
代理對象(Proxy):將通知應用到目標對象以後被動態建立的對象。能夠簡單地理解爲,代理對象的功能等於目標對象的核心業務邏輯功能加上共有功能。代理對象對於使用者而言是透明的,是程序運行過程當中的產物。
織入(Weaving):將切面應用到目標對象從而建立一個新的代理對象的過程。這個過程能夠發生在編譯期、類裝載期及運行期,固然不一樣的發生點有 着不一樣的前提條件。譬如發生在編譯期的話,就要求有一個支持這種AOP實現的特殊編譯器;發生在類裝載期,就要求有一個支持AOP實現的特殊類裝載器;只 有發生在運行期,則可直接經過Java語言的反射機制與動態代理機制來動態實現。