AOP相關術語
先了解AOP的相關術語:
1. 通知(Advice):
通知定義了切面是什么以及何時使用嘶卧。描述了切面要完成的工作和何時需要執(zhí)行這個工作嚷闭。
2. 連接點(Joinpoint):
程序能夠應用通知的一 個“時機”苛吱,這些“時機”就是連接點扣典,例如方法被調(diào)用時唆鸡、異常被拋出時等等兄裂。
3. 切入點(Pointcut)
通知定義了切面要發(fā)生的“故事”和時間池凄,那么切入點就定義了“故事”發(fā)生的地點抡驼,例如某個類或方法的名稱,spring中允許我們方便的用正則表達式來指定
4. 切面(Aspect)
通知和切入點共同組成了切面:時間肿仑、地點和要發(fā)生的“故事”
5. 引入(Introduction)
引入允許我們向現(xiàn)有的類添加新的方法和屬性(spring提供了一個方法注入的功能)
6. 目標(Target)
即被通知的對象致盟,如果沒有AOP,那么它的邏輯將要交叉別的事務邏輯碎税,有了AOP之后它可以只關注自己要做的事(AOP讓他做愛做的事)
7. 代理(proxy)
應用通知的對象,詳細內(nèi)容參見設計模式里面的代理模式
8. 織入(Weaving)
把切面應用到目標對象來創(chuàng)建新的代理對象的過程馏锡,織入一般發(fā)生在如下幾個時機:
(1) 編譯時:當一個類文件被編譯時進行織入雷蹂,這需要特殊的編譯器才可以做的到,例如AspectJ的織入編譯器
(2) 類加載時:使用特殊的ClassLoader在目標類被加載到程序之前增強類的字節(jié)代碼
(3) 運行時:切面在運行的某個時刻被織入,SpringAOP就是以這種方式織入切面的杯道,原理應該是使用了JDK的動態(tài)代理技術
基本步驟
- 創(chuàng)建通知:實現(xiàn)這幾個接口匪煌,把其中的方法實現(xiàn)了
- 定義切點和通知者:在Spring配制文件中配置這些信息
- 使用ProxyFactoryBean來生成代理
實現(xiàn)例子
首先一個Sleepable
接口
public interface Sleepable{
void sleep();
}
然后寫一個human
類實現(xiàn)這個接口
public Human implements Sleepable{
public void sleep(){
System.out.println("睡覺了");
}
}
最基本的是脫穿衣服,失眠的人還要吃安眠藥什么的,但是這些動作與純粹的睡覺這一“業(yè)務邏輯”是不相干的党巾,如果把這些代碼全部加入到sleep方法中萎庭,是不是有違單一職責呢?昧港,這時候我們就需要AOP了擎椰。
編寫一個SleepHelper
類,它里面包含了睡覺的輔助工作,用AOP術語來說它就應該是通知(Advice)了创肥,我們需要實現(xiàn)上面的接口
public class SleepHelper implements MethodBeforeAdvice,AfterReturningAdvice{
public void before(Method mtd, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("通常情況下睡覺之前要脫衣服");
}
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
System.out.println("起床后要先穿衣服");
}
}
然后在bean.xml中進行配置
<bean id="sleepHelper" class="test.spring.aop.bean.SleepHelper">
</bean>
這樣就創(chuàng)建了一個advice
進一步配置
<aop:config>
<aop:pointcut expression="execution(* com.gavin.exam.service..*.*(..))" id="pc"/>
<!-- advisor的配置
<aop:advisor pointcut-ref="pc" advice-ref="logMethodTimeAdvice" order="1"/>
-->
<!--aspect 的配置-->
<aop:aspect id="logMethodTimeAspect" ref="logMethodTimeAspect">
<aop:pointcut expression="execution(* com.gavin.exam.service..*.*(..))" id="businessService"/>
<aop:after pointcut-ref="businessService" method="doAfter"/>
<aop:around pointcut-ref="businessService" method="doAround"/>
</aop:aspect>
</aop:config>
其中Pointcut
定義了切入點达舒,代表了生效的范圍。