連接點(diǎn) JointPoint
表示需要在程序中插入橫切關(guān)注點(diǎn)的擴(kuò)展點(diǎn)奈懒,連接點(diǎn)可能是類初
始化区宇、方法執(zhí)行泌豆、方法調(diào)用救欧、字段調(diào)用或處理異常等等衰粹,Spring
只支持方法執(zhí)行連接點(diǎn)
切入點(diǎn) Pointcut
選擇一組相關(guān)連接點(diǎn)的模式,即可以認(rèn)為連接點(diǎn)的集合笆怠,Spring
支持perl5正則表達(dá)式和AspectJ切入點(diǎn)模式铝耻,Spring默認(rèn)使用
AspectJ語法
通知 Advice
在連接點(diǎn)上執(zhí)行的行為,通知提供了在AOP中需要在切入點(diǎn)所選
擇的連接點(diǎn)處進(jìn)行擴(kuò)展現(xiàn)有行為的手段;在Spring中通過代理模
式實(shí)現(xiàn)AOP
方面/切面 Aspect
橫切關(guān)注點(diǎn)的模塊化瓢捉,比如上邊提到的日志組件频丘。可以認(rèn)為是通知泡态、引入和切入點(diǎn)的組合搂漠;在Spring中可以使用Schema和@AspectJ方式進(jìn)行組織實(shí)現(xiàn)。
目標(biāo)對(duì)象 Target Object
需要被織入橫切關(guān)注點(diǎn)的對(duì)象某弦,即該對(duì)象是切入點(diǎn)選擇的對(duì)象桐汤,需
要被通知的對(duì)象,從而也可稱為“被通知對(duì)象”靶壮;由于Spring
AOP 通過代理模式實(shí)現(xiàn)怔毛,從而這個(gè)對(duì)象永遠(yuǎn)是被代理對(duì)象。
AOP代理 AOP Proxy
AOP框架使用代理模式創(chuàng)建的對(duì)象腾降,從而實(shí)現(xiàn)在連接點(diǎn)處插入通
知(即應(yīng)用切面)拣度,就是通過代理來對(duì)目標(biāo)對(duì)象應(yīng)用切面。在
Spring中蜂莉,AOP代理可以用JDK動(dòng)態(tài)代理或CGLIB代理實(shí)現(xiàn)蜡娶,而通
過攔截器模型應(yīng)用切面混卵。
織入 Weaving
織入是一個(gè)過程映穗,是將切面應(yīng)用到目標(biāo)對(duì)象從而創(chuàng)建出AOP代理對(duì)象的過程,織入可以在編譯期幕随、類裝載期蚁滋、運(yùn)行期進(jìn)行。
前置通知 Before Advice
在切入點(diǎn)選擇的連接點(diǎn)處的方法之前執(zhí)行的通知赘淮,該通知不影響正常程序執(zhí)行流程辕录。
后置通知 After Advice
? 在切入點(diǎn)選擇的連接點(diǎn)處的方法之后執(zhí)行的通知
? 后置返回通知(After returning Advice)
? 后置異常通知(After throwing Advice)
? 后置最終通知(After finally Advice)
環(huán)繞通知 Around Advice
? 環(huán)繞著在切入點(diǎn)選擇的連接點(diǎn)處的方法所執(zhí)行的通知
定義切入點(diǎn),就是執(zhí)行的條件梢卸。切入點(diǎn)的方法不用任何代碼走诞,返回值是void,最重要的是執(zhí)行的條件的表達(dá)式蛤高。
@Pointcut("execution(* com.test.service.*.*(..))")
public void executeService()
{
}
1)execution:用于匹配子表達(dá)式蚣旱。
//匹配com.cjm.model包及其子包中所有類中的所有方法,返回類型任意戴陡,方法參數(shù)任意
@Pointcut("execution(* com.cjm.model..*.*(..))")
public void before(){}
2)within:用于匹配連接點(diǎn)所在的Java類或者包塞绿。
//匹配Person類中的所有方法
@Pointcut("within(com.cjm.model.Person)")
public void before(){}
//匹配com.cjm包及其子包中所有類中的所有方法
@Pointcut("within(com.cjm..*)")
public void before(){}
3) this:用于向通知方法中傳入代理對(duì)象的引用。
@Before("before() && this(proxy)")
public void beforeAdvide(JoinPoint point, Object proxy){
//處理邏輯
}
4)target:用于向通知方法中傳入目標(biāo)對(duì)象的引用恤批。
@Before("before() && target(target)
public void beforeAdvide(JoinPoint point, Object proxy){
//處理邏輯
}
5)args:用于將參數(shù)傳入到通知方法中异吻。
@Before("before() && args(age,username)")
public void beforeAdvide(JoinPoint point, int age, String username){
//處理邏輯
}
6)@within :用于匹配在類一級(jí)使用了參數(shù)確定的注解的類,其所有方法都將被匹配喜庞。
@Pointcut("@within(com.cjm.annotation.AdviceAnnotation)") - 所有被@AdviceAnnotation標(biāo)注的類都將匹配
public void before(){}
7)@target :和@within的功能類似诀浪,但必須要指定注解接口的保留策略為RUNTIME棋返。
@Pointcut("@target(com.cjm.annotation.AdviceAnnotation)")
public void before(){}
8)@args :傳入連接點(diǎn)的對(duì)象對(duì)應(yīng)的Java類必須被@args指定的Annotation注解標(biāo)注。
@Before("@args(com.cjm.annotation.AdviceAnnotation)")
public void beforeAdvide(JoinPoint point){
//處理邏輯
}
9)@annotation :匹配連接點(diǎn)被它參數(shù)指定的Annotation注解的方法雷猪。也就是說懊昨,所有被指定注解標(biāo)注的方法都將匹配。
@Pointcut("@annotation(com.cjm.annotation.AdviceAnnotation)")
public void before(){}
10)bean:通過受管Bean的名字來限定連接點(diǎn)所在的Bean春宣。該關(guān)鍵詞是Spring2.5新增的酵颁。
@Pointcut("bean(person)")
public void before(){}
請(qǐng)注意我們使用了“&&”操作符把execution()和within()指示器連接在一起形成與(and)關(guān)系(切點(diǎn)必須匹配所有的指示器)。類似地,我們可以使用“||”操作符來標(biāo)識(shí)或(or)關(guān)系,而使用“!”操
作符來標(biāo)識(shí)非(not)操作月帝。
因?yàn)椤?amp;”在XML中有特殊含義,所以在Spring的XML配置里面描述切點(diǎn)時(shí),我們可以使用and來代替“&&”躏惋。同樣,or和not可以分別用來代替“||”和“!”。
通知參數(shù)
任何通知方法可以將第一個(gè)參數(shù)定義為org.aspectj.lang.JoinPoint類型(環(huán)繞通知需要定義第一個(gè)參數(shù)為ProceedingJoinPoint類型嚷辅,它是 JoinPoint 的一個(gè)子類)簿姨。JoinPoint接口提供了一系列有用的方法,比如 getArgs()(返回方法參數(shù))簸搞、getThis()(返回代理對(duì)象)扁位、getTarget()(返回目標(biāo))、getSignature()(返回正在被通知的方法相關(guān)信息)和 toString()(打印出正在被通知的方法的有用信息)
切入點(diǎn)表達(dá)式
定義切入點(diǎn)時(shí)需要一個(gè)包含名字和任意參數(shù)的簽名趁俊,還有一個(gè)切入點(diǎn)表達(dá)式域仇,就是* findById*(..)這一部分。
切入點(diǎn)表達(dá)式的格式:execution([可見性] 返回類型 [聲明類型].方法名(參數(shù)) [異常])
其中【】中的為可選寺擂,其他的還支持通配符的使用:
*:匹配所有字符
..:一般用于匹配多個(gè)包暇务,多個(gè)參數(shù)
+:表示類及其子類
運(yùn)算符有:&&、||怔软、!
在使用spring框架配置AOP的時(shí)候垦细,不管是通過XML配置文件還是注解的方式都需要定義pointcut”切入點(diǎn)”
例如定義切入點(diǎn)表達(dá)式 execution (* com.sample.service.impl..*. *(..))
execution()是最常用的切點(diǎn)函數(shù),其語法如下所示:
整個(gè)表達(dá)式可以分為五個(gè)部分:
1挡逼、execution(): 表達(dá)式主體括改。
2、第一個(gè)*號(hào):表示返回類型家坎, *號(hào)表示所有的類型嘱能。
3、包名:表示需要攔截的包名乘盖,后面的兩個(gè)句點(diǎn)表示當(dāng)前包和當(dāng)前包的所有子包焰檩,com.sample.service.impl包、子孫包下所有類的方法订框。
4析苫、第二個(gè)*號(hào):表示類名,*號(hào)表示所有的類。
5衩侥、*(..):最后這個(gè)星號(hào)表示方法名国旷,*號(hào)表示所有的方法,后面括弧里面表示方法的參數(shù)茫死,兩個(gè)句點(diǎn)表示任何參數(shù)
相關(guān)博客:
http://www.cnblogs.com/lic309/p/4079194.html
http://blog.csdn.net/lk7688535/article/details/51989746