AOP 即 Aspect Oriental Program 面向切面編程 java
先來一個栗子:express
<aop:config> <aop:pointcut id="loggerCutpoint" expression= "execution(* com.how2java.service.ProductService.*(..)) "/> <aop:aspect id="logAspect" ref="loggerAspect"> <aop:after pointcut-ref="loggerCutpoint" method="log"/> </aop:aspect> </aop:config>
這個配置過程是什麼含義呢?編程
<aop:pointcut id="loggerCutpoint" expression="execution(* com.how2java.service.ProductService.*(..)) "/>
這一句是聲明切入點,切入點的 id 叫 loggerCutPoint ,用來標記這個切入點,函數
這個expression表示:知足expression中的方法調用以後,就會去進行切面操做,相似於觸發了切面:網站
第一個 * 表明返回任意類型
com.how2java.service.ProductService.* 表示包名以 com.how2java.service.ProductService 開頭的類的任意方法(第二個*表示任意方法,通配符確定知道吧)
(..) 表示方法的參數是任意數量和類型spa
簡單說就是,只要com.how2java.service這個包中的ProductService類的任意一個函數被調用,無論你的返回值是什麼,都會觸發開關,我就會去執行切面,也就是輔助功能,可是輔助功能是什麼呢,就是下面兩句:代理
<aop:aspect id="logAspect" ref="loggerAspect"> 日誌
<aop:after pointcut-ref="loggerCutpoint" method="log"/> code
</aop:aspect>xml
這兩句是定義了一個切面,上面說只要觸發開關,就會去執行切面,就是指的這裏的切面,所謂切面,就是一個類中的方法而已,搞的這個高大上。。。
id表明這個切面的名字,ref就是指的方法所在的類,method表明的就是方法的名字,
pointcut-ref="loggerCutpoint" 這個就是表示我這個切面是和上面的切點關聯起來的(一個切點是能夠關聯多個切面的,一個切面只能關聯一個方法),只要上面的切點被觸發,我就會到這裏來執行一些輔助功能,搞得和單片機的中斷同樣,
after表示在切入點觸發以後來執行我這個中斷,固然也有before,一共有五個before,after,After-returning ,After-throwing,Around。
在 method 參數後面,還能夠加上參數列表。
正文開始
網站的功能分爲核心功能和輔助功能,輔助功能叫作切面
AOP的過程分爲兩步:1,在業務類中插入切入點,2,將切入點和切面類關聯起來
業務類就是核心類,就是網站的主要功能,切面就是輔助功能,日誌,統計之類的
經過配置,能夠實現,在某個方法調用的時候,觸發別的方法執行,就好像在監視目標方法,你被執行,就觸發我執行。
AOP術語
1,通知:
通知定義了切面要完成的工做內容和什麼時候完成工做,就是何時去作輔助功能,功能具體是什麼代碼
五種類型
Before——在方法調用以前調用通知
After——在方法完成以後調用通知,不管方法執行成功與否
After-returning——在方法執行成功以後調用通知
After-throwing——在方法拋出異常後進行通知
Around——通知包裹了被通知的方法,在被通知的方法調用以前和調用以後執行自定義的行爲
前四個好理解的,最後一個
around 表示切面在被監視的函數運行先後都會執行,
下面是切面要執行的函數 log,log函數有一個形參 joinPoint 這個能夠理解爲斷點,中間一句表明的就是被監視的程序運行,在被監視的程序運行時,能夠替換他的形參,這個是 around 厲害的地方,若是被監視的程序,運行的時候輸入的是一個haha字符串做爲實參,可是通過log方法以後,這個參數就被替換爲abc了
public Object log(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("我在被監視程序以前。。。"); Object object = joinPoint.proceed(new Object[]{"abc"}); System.out.println("我在被監視程序以後。。。" ); return object; }
2,鏈接點:
在執行正常的功能時,可以插入切面的點。能夠做爲切入點的點。備選點。
鏈接點能夠是調用方法時、拋出異常時、甚至修改字段時,在這些點,就能夠去執行切面。
3,切面:
定義:切面是通知和切點的集合,通知和切點共同定義了切面的所有功能——它是什麼,在什麼時候何處完成其功能。
聲明切面:
在Spring中,切面就是一個包含通知和切點的對象,是一個Bean,Bean的字段和方法就是該切面的狀態和行爲,還要經過配置,來指定切入點和通知實現
在xml中,切面使用<aop:aspect>標籤指定,ref屬性用來引用切面支持Bean。這個bean裏面就是用來執行要作的輔助功能的。
4,切點:
定義:若是通知定義了「什麼」和「什麼時候」。那麼切點就定義了「何處」。切點會匹配通知所要織入的一個或者多個鏈接點。一般使用明確的類或者方法來指定這些切點。
做用:定義通知被應用的位置(在哪些鏈接點)
切入點的聲明:
切入點在Spring也是一個Bean。
切點的聲明有三種定義方式:
1)在<aop:config>標籤下使用<aop:pointcut>聲明一個切入點Bean,該切入點能夠被多個切面使用,對於須要共享使用的切入點最好使用該方式,該切入點使用id屬性指定Bean名字,在通知定義時使用pointcut-ref屬性經過該id引用切入點,expression屬性指定切入點表達式
<aop:config> <aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/> <aop:aspect ref="aspectSupportBean"> <aop:before pointcut-ref="pointcut" method="before"/> </aop:aspect> </aop:config>
2)在<aop:aspect>標籤下使用<aop:pointcut>聲明一個切入點Bean,該切入點能夠被多個切面使用,但通常該切入點只被該切面使用,固然也能夠被其餘切面使用,但最好不要那樣使用,該切入點使用id屬性指定Bean名字,在通知定義時使用pointcut-ref屬性經過該id引用切入點,expression屬性指定切入點表達式:
<aop:config> <aop:aspect ref="aspectSupportBean"> <aop:pointcut id=" pointcut" expression="execution(* cn.javass..*.*(..))"/> <aop:before pointcut-ref="pointcut" method="before"/> </aop:aspect> </aop:config>
3)匿名切入點Bean,能夠在聲明通知時經過pointcut屬性指定切入點表達式,該切入點是匿名切入點,只被該通知使用:
<aop:config> <aop:aspect ref="aspectSupportBean"> <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterFinallyAdvice"/> </aop:aspect> </aop:config>
5,引入:
引入容許咱們向現有的類中添加方法或屬性
6,織入:
織入是將切面應用到目標對象來建立的代理對象過程。
切面在指定的鏈接點被織入到目標對象中,在目標對象的生命週期中有多個點能夠織入