spring實現(xiàn)aop

AOP相關(guān)術(shù)語

先了解AOP的相關(guān)術(shù)語:

1. 通知(Advice):

通知定義了切面是什么以及何時使用。描述了切面要完成的工作和何時需要執(zhí)行這個工作。

2. 連接點(Joinpoint):

程序能夠應(yīng)用通知的一 個“時機”,這些“時機”就是連接點,例如方法被調(diào)用時、異常被拋出時等等。

3. 切入點(Pointcut)

通知定義了切面要發(fā)生的“故事”和時間,那么切入點就定義了“故事”發(fā)生的地點,例如某個類或方法的名稱,spring中允許我們方便的用正則表達式來指定

4. 切面(Aspect)

通知和切入點共同組成了切面:時間、地點和要發(fā)生的“故事”

5. 引入(Introduction)

引入允許我們向現(xiàn)有的類添加新的方法和屬性(spring提供了一個方法注入的功能)

6. 目標(Target)

即被通知的對象,如果沒有AOP,那么它的邏輯將要交叉別的事務(wù)邏輯,有了AOP之后它可以只關(guān)注自己要做的事(AOP讓他做愛做的事)

7. 代理(proxy)

應(yīng)用通知的對象,詳細內(nèi)容參見設(shè)計模式里面的代理模式

8. 織入(Weaving)

把切面應(yīng)用到目標對象來創(chuàng)建新的代理對象的過程,織入一般發(fā)生在如下幾個時機:
(1) 編譯時:當一個類文件被編譯時進行織入,這需要特殊的編譯器才可以做的到,例如AspectJ的織入編譯器
(2) 類加載時:使用特殊的ClassLoader在目標類被加載到程序之前增強類的字節(jié)代碼
(3) 運行時:切面在運行的某個時刻被織入,SpringAOP就是以這種方式織入切面的,原理應(yīng)該是使用了JDK的動態(tài)代理技術(shù)

基本步驟

  1. 創(chuàng)建通知:實現(xiàn)這幾個接口,把其中的方法實現(xiàn)了
  2. 定義切點和通知者:在Spring配制文件中配置這些信息
  3. 使用ProxyFactoryBean來生成代理

實現(xiàn)例子

首先一個Sleepable接口
public interface Sleepable{
    void sleep(); 
}
然后寫一個human類實現(xiàn)這個接口
public Human implements Sleepable{
   public void sleep(){
      System.out.println("睡覺了");
   }
}

最基本的是脫穿衣服,失眠的人還要吃安眠藥什么的,但是這些動作與純粹的睡覺這一“業(yè)務(wù)邏輯”是不相干的,如果把這些代碼全部加入到sleep方法中,是不是有違單一職責呢?,這時候我們就需要AOP了。

編寫一個SleepHelper類,它里面包含了睡覺的輔助工作,用AOP術(shù)語來說它就應(yīng)該是通知(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定義了切入點,代表了生效的范圍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容