基於註解的Sping AOP詳解

2021-07-28 17:50:59 字數 4295 閱讀 8994

一、建立基礎業務

package com.kang.sping.aop.service;

import org.springframework.stereotype.service;

//使用註解@service宣告bean

@service

public class userservice

public string delete()

public void edit()

}

二、配置sping的xml檔案

<?xml version="1.0" encoding="utf-8"?>		

三、建立增強處理類

package com.kang.sping.aop.entities;

import org.aspectj.lang.joinpoint;

import org.aspectj.lang.proceedingjoinpoint;

import org.aspectj.lang.annotation.*;

import org.springframework.core.annotation.order;

import org.springframework.stereotype.component;

/* * @component註解宣告bean

* @aspect註解宣告這是乙個切面

* 在同乙個連線點上應用不止乙個切面時, 除非明確指定, 否則它們的優先順序是不確定的.

* 切面的優先順序可以利用 @order 註解指定.值越小, 優先順序越高。

*/@component

@aspect

//@order(0) 設定優先順序

public class operator

/* * @before 表示在目標方法執行之前執行,@before 裡面的是切入點表示式或切入點函式 可以在通知方法中宣告乙個型別為 joinpoint

* 的引數. 然後就能訪問鏈結細節,如方法名稱和引數值.

* 獲取方法名:joinpoint.getsignature().getname()

* 獲取引數列表:joinpoint.getargs();

*/@before("pointcut()")

public void dobefore(joinpoint joinpoint)

@after("pointcut()")

public void doafter(joinpoint joinpoint)

/* * @afterreturning(pointcut = "pointcut()", returning = "returnval")

* returning:指定乙個返回值形參名,代表了目標方法的返回值, 增強處理定義的方法可以通過該引數訪問目標方法的返回值。

* 因此必須在通知方法的簽名中新增乙個同名引數.afterreturn(joinpoint joinpoint, object returnval)

* 在執行時, spring aop 會通過這個引數傳遞返回值. 與@after的區別:

* after增強處理無論目標方法如何結束(執行成功或者異常終止),都會執行.

* afterreturning增強處理只有在目標方法執行成功後才會執行。

*/@afterreturning(pointcut = "pointcut()", returning = "returnval")

public void afterreturn(joinpoint joinpoint, object returnval)

/* * @afterthrowing 只在連線點丟擲異常時才執行異常通知。將 throwing 屬性新增到 @afterthrowing 註解中,

* 也可以訪問連線點丟擲的異常。 throwable 是所有錯誤和異常類的超類. 所以在異常通知方法可以捕獲到任何錯誤和異常.

* 如果只對某種特殊的異常型別感興趣, 可以將引數宣告為其他異常的引數型別. 然後通知就只在丟擲這個型別及其子類的異常時才被執行.

*/@afterthrowing(pointcut = "pointcut()", throwing = "error")

public void afterthrowing(joinpoint joinpoint, throwable error)

/* * @around 對於環繞通知來說, 連線點的引數型別必須是 proceedingjoinpoint . 它是 joinpoint 的子介面,

* 允許控制何時執行, 是否執行連線點。在環繞通知中需要明確呼叫 proceedingjoinpoint 的 proceed()

* 方法來執行被**的方法,可以傳入乙個object物件,該陣列中的值將被傳入目標方法作為執行方法的實參。 如果沒有呼叫proceed()就會導致通知被執行了, 但目標方法沒有被執行。 注意:

* 環繞通知的方法需要返回目標方法執行之後的結果, 即呼叫 joinpoint.proceed(); 的返回值, 否則會出現空指標異常

* 事實上,在around通知方法中可以修改原方法的返回值。而afterreturning得到的返回值也是由around決定的。

*/@around("pointcut()")

public object around(proceedingjoinpoint pjp) catch (throwable e)

return null;}}

四、編寫測試方法

1、測試沒有返回值的方法(add)

package com.kang.sping.aop.main;

import com.kang.sping.aop.service.userservice;

public class test

}

測試結果

分析以上結果可以得出以下結論 :

(1)通知執行的優先順序

進入目標方法時,先織入around,再織入before,退出目標方法時,先織入around,再織入afterreturning,最後才織入after。

注意:spring aop的環繞通知會影響到afterthrowing通知的執行,不要同時使用!同時使用也沒啥意義。

(2)around可以改變原方法的返回值,而afterreturning得到的返回值實際上是around通知方法的返回值。

2、測試有返回值的方法(delete)

package com.kang.sping.aop.main;

import com.kang.sping.aop.service.userservice;

public class test

}

測試結果:

可以看到,around的返回值影響了afterreturning得到的返回值和原方法執行後的最終返回值。

3、測試出現異常的方法(edit)(這裡將@around通知方法注釋掉,否則會影響afterthrowing的執行)

package com.kang.sping.aop.main;

import com.kang.sping.aop.service.userservice;

public class test

}

測試結果:

可以看到afterthrowing方法的執行在after方法之後。

五、總結

around增強處理可以獲得目標方法的最大控制權,既可以完全控制目標方法的執行,也可以改變執行目標方法的引數,還可以改變目標方法的返回值。任何通知(advice)方法可以將第乙個引數定義為 org.aspectj.lang.joinpoint 型別。joinpoint 介面提供了一系列有用的方法, 比如 getargs() (返回方法引數)、getthis() (返回**物件)、gettarget() (返回目標)、getsignature() (返回正在被通知的方法相關資訊)和 tostring() (列印出正在被通知的方法的有用資訊。)

sping AOP基於註解的配置

1.bean.xml匯入註解約束 accountserviceimpl加入容器 賬戶的業務層實現類 service accountservice public class accountserviceimpl implements iaccountservice public void update...

sping AOP底層原理(詳解)

aop 面向切面程式設計,利用aop對業務邏輯各個方面進行隔離,從而使業務邏輯的各個方面耦合度進行降低,提高 的重用性,同時提高 的使用效率。底層原理 分兩種 1.有介面通過jdk動態 2.沒有介面通過cglib動態 jdk 動態 具體實現 通過使用proxy類的方法實現動態 1 呼叫newprox...

Spring基於註解的配置詳解

基礎類 public class student public void setsid integer sid public string getsname public void setsname string sname public string getsgrade public void s...