前面幾天介紹了Spring,IOC容器,bean的生命週期和初始化及銷燬過程,註解的使用。java
今天介紹一節純幹活,AOP的實現原理,看完這一篇,面試過程當中,不再要和麪試官尬聊:面向切面編程!引用場景在日誌,方法加強等等方面!面試
本文經過對AOP是什麼,使用場景,實現原理等方面,結合代碼等方式圖文介紹,用最簡短的語言文字描述,完全掌握AOP的使用方式,面試中介紹AOP時跟面試官侃侃而談,面試官只會對你說一個字:牛逼!spring
1、AOP介紹編程
AOP:面向切面編程【底層就是動態代理】,指程序在運行期間動態的將某段代碼切入到指定方法位置進行的編程方式。微信
使用AOP有什麼好處?測試
場景:例如定義一個方法,方法中要計算二者相除,方法中須要驗證被除數的數據是否符合邏輯(好比不能爲0),咱們固然能夠經過 if 條件方式將邏輯處理好。可是代碼略顯臃腫,此時能夠經過引入AOP,在執行計算以前將判斷邏輯處理好,以及在運算以後將對應的後置相關邏輯也加上,這樣不只不須要在代碼中寫大量的 if 等邏輯代碼,並且經過這種方式,對方法進行統一封裝引用。spa
接下來進行實例演示代理
創建配置類日誌
在pom.xml中引入spring-aspects依賴xml
新建實體類Calculator.java
在Calculator的div()方法運行以前,記錄一下日誌,運行後也記錄一下日誌,若是運行出異常,也將異常打印一下。可能實現的方式就會在方法體中每個都寫上相應的代碼,這樣方法多了,會顯得很是的冗餘及耦合。
此時須要一個日誌切面類,來將好比日誌等方法進行統一管理。
日誌切面類的方法須要動態感知到div()方法運行到哪裏了,而後再執行,若是除法開始,就日誌開始方法,也叫通知方法,分如下幾種:
前置通知:logStart(),在目標方法(div)運行以前運行 (@Before)
後置通知:logEnd(),在目標方法(div)運行結束以後運行,不管正常或異常結束 (@After)
返回通知:logReturn,在目標方法(div)正常返回以後運行 (@AfterReturning)
異常通知:logException,在目標方法(div)出現異常後運行(@AfterThrowing)
環繞通知:以上沒寫,動態代理,手動執行目標方法運行joinPoint.procced(),最底層通知,手動指定執行目標方法(@Around),執行以前至關於前置通知,執行以後至關於返回通知,其實就是經過反射執行目標對象的鏈接點處的方法。
給日誌切面類LogAspect的方法標註什麼時候運行(即通知註解)
怎麼加入呢?
Spring沒法區別【切面類】,哪一個是業務類,在這裏給LogAspects類加上@Aspect註解便可聲明爲切面類。
同時,若不想區分切入了哪一個方法及參數類型和個數,能夠有以下指定方式:
在這裏又發現問題:註解裏的內容是冗餘重複的, 公共的代碼應該抽出來封裝
有了以上操做, 咱們還須要將切面類和被切面的類, 都加入到容器中,在配置類中引入
是否是就完了呢?並無
須要開啓基於註解的AOP模式
給配置類中加@EnableAspectJAutoProxy[必定得加上,關鍵]
注意:在spring之後會有不少@EnableXXXX,表示開啓某項功能,取代XML配置
測試一下:新建一個測試類Cap10Test.java
同窗們在測試的過程當中,應該怎麼測?很容易出問題。
你們可能會這麼寫:
沒用到容器,確定是不行的,獲取bean時使用IOC容器取出bean
總結:
AOP看起來很麻煩, 只要3步就能夠了:
1. 將業務邏輯組件和切面類都加入到容器中, 告訴spring哪一個是切面類(@Aspect)
2. 在切面類上的每一個通知方法上標註通知註解, 告訴Spring什麼時候運行(寫好切入點表達式,參照官方文檔)
3. 開啓基於註解的AOP模式 @EableXXXX
小夥伴們能夠看到,不管是在工做中,仍是面試回答中,對AOP僅僅停留在面向切面編程層面上是遠遠不夠的,還須要深刻對裏面的流程進行了解,本文針對AOP的原理,實現方式進行了介紹,但願後續小夥伴在工做和麪試中經過本文AOP的介紹,對AOP的引用可以更加靈活,面試回答更加遊刃有餘。
下一篇將深刻到AOP源碼,對AOP進行深刻解析。
若是以爲好的話,能夠關注,點贊和轉發呀~
關注微信公衆號【Java極客思惟】
Java極客思惟
微信掃一掃,關注公衆號