AOP術語:spring
一、通知(Adivce)this
通知定義了切面是什麼以及什麼時候使用。除了描述切面要完成的工做,通知還解決了什麼時候執行這個工做的問題。它應該應用於某個方法spa
個方法被調用以前?以後?以前和以後?仍是隻在方法拋出異常時?代理
String 切面能夠應用5種類型的通知orm
a、Before -- 在方法被調用以前調用通知對象
b、After -- 在方法被調用以後調用通知接口
c、After-returning -- 在方法成功執行以後調用通知生命週期
d、After-throwing -- 在方法拋出異常後調用通知ci
e、Around -- 通知包裹了被通知的方法,在被通知的方法調用以前和調用以後執行自定的行爲get
二、鏈接點(Joinpoint)
鏈接點是在應用執行過程當中可以插入切面的一個點。
三、切點(Poincut)
四、切面(Aspect)
五、引入(Introduction)
引入容許咱們向現有的類添加新方法或屬性。例如,咱們能夠建立以個Auditable通知類,該類記錄了對象最後一次修改時的
狀態。這很簡單,只需一種方法,setLastModified(Date),和一個實例變量來保存這個狀態。而後,這個新方法和實例變量就
能夠被引入到現有的類中。從而能夠在無需修改這類現有的類的狀況下,讓他們具備新的行爲和狀態。
六、織入(Weaving)
織入是將切面應用到目標對象來建立新的代理對象的過程。切面在指定的鏈接點被織入到目標對象中。在目標對象的生命週期裏
有多個點能夠進行織入。
a、編譯期 -- 切面在目標類編譯時被織入。這種方式須要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。
b、類加載器 -- 切面在目標類加載到JVM時被織入。這種方式須要特殊的類加載器(ClassLoader),他能夠在目標類被引入
應用以前加強該目標類的字節碼。AspectJ5的LTW(loading-time weaving)就支持以這種方式織入切面
c、運行期 -- 切面在應用運行的某個時刻被織入。通常狀況下,在織入切面時,AOP容器會爲目標對象動態的建立一個代理對象。
Spring AOP 就是以這種方式織入切面的。
Spring 只支持方法鏈接點。 AspectJ和Jboss,除了方法切點,他們還提供了字段和構造器接入點 。Spring缺乏對字段鏈接點的支持,
沒法讓咱們建立細粒度的通知,例如攔截對象字段的修改。並且Spring也不支持構造器鏈接點,咱們也沒法在Bean建立時應用通知。
Spring 的 AOP 配置元素簡化了基於pojo切面的聲明
AOP配置元素 描述
<aop:advisor> 定義aop通知器
<aop:after> 定義aop後置通知(無論被通知的方法是否執行成功)
<aop:after-returning> 定義AOP after-returning通知
<aop:after-throwing> 定義after-throwing通知
<aop:around> 定義AOP環繞通知
<aop:aspect> 定義切面
<aop:aspectj-autoproxy> 啓用@Aspecctj註解驅動的去切面
<aop:before> 定義AOP前置通知
<aop:config> 頂層的aop配置,大多數的<aop:*>元素必須包含在<aop:config>元素內
<aop:declare-parents> 爲被通知的對象引入額外的接口,並透明的實現
<aop:pointcut> 定義切點
經過切面引入新功能:
使用Spring AOP,咱們能夠爲Bean引入新的方法。代理攔截調用並委託給實現該方法的其餘對象。咱們須要注意的是,當引入接口的
方法被調用時,代理將此調用委託給實現了新接口的某個其餘獨享。實際上,Bean的實現被拆分到了多個類。
新功能:
package com.springinaction.springidol
public interface Contestant{
void receiveAward();
}
<aop:aspect>
<aop:declare-parents
type-matching = "com.springinaction.springidol.Performer+"
implement-interface="com.springinaction.springidol.Contestant"
default-impl="com.springinaction.springidol.GraciousContestant"
/>
</aop-aspect>
顧名思義,<aop:declare-parents>聲明瞭此切面所通知的Bean在對他的對象層次結構中擁有新的父類型。
具體到本示例中,類型匹配Perpormer接口(由types-match屬性指定)的那些Bean會實現Contestant接口(
由implements-interface屬性指定)。最後要解決的問題是Constestant接口中的方法實現來自於何處
這裏有兩種方式標識所引入接口的實現。在本示例中,咱們使用default-impl屬性經過他的全限定類名來顯示
指定Contestant的實現。或者,咱們還可使用delegate-ref屬性來標識.
<aop:aspect>
<aop:declare-parents
type-matching = "com.springinaction.springidol.Performer+"
implement-interface="com.springinaction.springidol.Contestant"
delegate-ref="contestaantDelegate"
/>
</aop-aspect>
delegate-ref 屬性引用了一個Spring Bean做爲引入的 委託。這須要在Spring上下文中存在一個ID爲contestantDelefate
的Bean。
<bean id="contestaantDelegate" class="com.springinaction.springidol.GraciousContestant"/>
使用def-impl來直接標識委託和間接使用delegate-ref的區別在於後者是Spring Bean,他自己能夠被注入,被通知,或者使用其餘Spring配置
spring藉助ApectJ的切點表達式語言來定義Spring切面
AspectJ指示器 描述
arg() 限制鏈接點匹配參數未指定類型的執行方法
@arg() 限制鏈接點匹配參數由指定註解標註的執行方法
execution() 用於匹配是鏈接點的執行方法
this() 顯示鏈接點匹配AOP代理的Bean應用爲指定類型的類
target() 限制鏈接點匹配目標對位爲指定類型的類
@target() 限制鏈接點匹配特定的執行對象,這些對象對應的類要具有指定類型的註解
within() 限制鏈接點匹配指定的類型
@with() 限制鏈接點匹配指定註解所標註的類型(當使用AOP時,方法定義在由指定的註解所標註的類裏)
@annotation 限制匹配帶有指定註解鏈接點