SpringAOP通知

spring(AOP通知)

切面
切面是封裝通用業務邏輯的組件,可以作用到其他組件上。是spring組件中的某個方法、無返回類型、參數類型與通知類型有關。
一個切面 開啓數據庫 關閉數據庫 開啓事務 檢查登錄賬號狀態 監測賬號權限
切點
用於指定哪些組件哪方法使用切面組件,Spring提供表達式來實現該制定。
通知
用於指定組件作用到目標組件的具體位置。

連接點(Joinpoint)
  增強程序執行的某個特定位置(要在哪個地方做增強操作)。Spring僅支持方法的連接點,既僅能在方法調用前,方法調用後,方法拋出異常時等這些程序執行點進行織入增強。
切點(Pointcut)
  切點是一組連接點的集合。AOP通過“切點”定位特定的連接點。通過數據庫查詢的概念來理解切點和連接點的關係再適合不過了:連接點相當於數據庫中的記錄,而切點相當於查詢條件。
增強(Advice)
  增強是織入到目標類連接點上的一段程序代碼。表示要在連接點上做的操作。
切面(Aspect)
  切面由切點和增強(引介)組成(可以包含多個切點和多個增強),它既包括了橫切邏輯的定義,也包括了連接點的定義,SpringAOP就是負責實施切面的框架,它將切面所定義的橫切邏輯織入到切面所指定的鏈接點中。

註解使用
@aspect 定義切面
@pointcut 定義切點
@before 標註Before Advice定義所在的方法
@afterreturning 標註After Returning Advice定義所在的方法
@afterthrowing 標註After Throwing Advice定義所在的方法
@after 標註 After(Finally) Advice定義所在的方法
@around 標註Around Advice定義所在的方法

包結構如下圖
在這裏插入圖片描述

1.AOP通知(配置xml文件)

QieMian1.java

public class QieMian1 {
    public void qianzhi(JoinPoint jp) {
        System.out.println("前置通知");
        Object [] os = jp.getArgs();
        for (Object object : os) {
            System.out.println("參數列表爲:"+object);
        }
    }
    
    public void houzhi(Object a) {
        System.out.println("後置通知"+a);
    }
    
    public void yichang(JoinPoint jp,Throwable ta) {
        System.out.println("異常通知");
        ta.printStackTrace();
    }
    
    public void zuizhong() {
        System.out.println("最終通知");
    }
    
    public void huanrao(ProceedingJoinPoint pjp) {
        try {
            System.out.println("環繞前");
            pjp.proceed();
            System.out.println("環繞後");
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            System.out.println("環繞異常");
            e.printStackTrace();
        }finally {
            System.out.println("環繞最終");
        }
    }
}

ApplicationContext.xml

<!-- 切面1 -->
    <bean id="qieMian1" class="com.zy.spring.tools.aop.QieMian1"></bean> <!-- 創建一個切面的bean -->
    <aop:config> <!-- aop配置標籤 -->
        <aop:pointcut expression="execution(* com.zy.spring.service.*.*(..))" id="pc1"/> <!-- 創建一個切點 -->
        <aop:aspect order="1"  ref="qieMian1"><!-- 創建一個切面   order是切面創建的順序   ref鏈接上面創建的切面bean -->
            <aop:before method="qianzhi" pointcut-ref="pc1"/><!-- 前置通知 -->
            <aop:after-returning method="houzhi" pointcut-ref="pc1" returning="a"/> <!-- 後置通知   returning返回參數-->
            <aop:after-throwing method="yichang" pointcut-ref="pc1" throwing="ta"/> <!-- 異常通知   throwing返回參數-->
            <aop:after method="zuizhong" pointcut-ref="pc1"/> <!-- 最終通知 -->
            <aop:around method="huanrao" pointcut-ref="pc1"/> <!-- 環繞通知 -->
        </aop:aspect>
    </aop:config>

1、execution:
Spring AOP僅支持方法執行類型的Joinpoint 所以execution將會是我們用的最多的標誌符,用它來幫我們匹配擁有指定方法前面的Joinpoint。

匹配方法execution

execution(返回類型 類的路徑.類名.函數名(參數類型1,參數類型2))

execution(String com.chinasofti.Target.save(String))

execution(* com.chinasofti.Target.save(String))

execution(* com.chinasofti.*.save(String))

execution(* com.chinasofti..(String))

execution(* com….(…))
2、Within:
Within標誌符只接受類型聲明,它將匹配指定類型下所有的Joinpoint。

匹配類within

匹配到類
<aop:pointcut id=“targetPintcut” expression=“within(com.chinasofti.Target)”/>
調用這個類中的任何一個方法,都會走通知

匹配到包下的類
<aop:pointcut id=“targetPintcut” expression=“within(com.chinasofti.*)”/>
調用這個包下的任何一個類中的方法,都會走通知

匹配到包下及子包下的類
<aop:pointcut id=“targetPintcut” expression=“within(com…*)”/>
調用com這個包下的,所有子包及其一個類中的方法,都會走通知

2.AOP通知(註解配置)

QieMian2.java

@Aspect//定義切面
@Component//註冊bean
public class QieMian2 {
    @Pointcut("execution(* com.zy.spring.service.*.*(..))") //標記切點規則
    public void pointcut() {};//創建一個空的方法,相當於切入方法
    
    @Before("pointcut()") //前置通知  切點就是上面創建的pointcut()方法
    public void qianzhi(JoinPoint jp) {
        System.out.println("註解前置通知");
        Object [] os = jp.getArgs();
        for (Object object : os) {
            System.out.println("參數列表爲:"+object);
        }
    }
    @AfterReturning(pointcut="pointcut()",returning="a")//後置通知  returning是方法中定義的參數
    public void houzhi(Object a) {
        System.out.println("註解後置通知"+a);
    }
    @AfterThrowing(pointcut="pointcut()",throwing="ta")//異常通知  throwing是方法中定義的參數
    public void yichang(JoinPoint jp,Throwable ta) {
        System.out.println("註解異常通知");
        ta.printStackTrace();
    }
    @After("pointcut()")//最終通知
    public void zuizhong() {
        System.out.println("註解最終通知");
    }
    @Around("pointcut()")//環繞通知
    public void huanrao(ProceedingJoinPoint pjp) {
        try {
            System.out.println("註解環繞前");
            pjp.proceed();//放行
            System.out.println("註解環繞後");
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            System.out.println("註解環繞異常");
            e.printStackTrace();
        }finally {
            System.out.println("註解環繞最終");
        }
    }
}

ApplicationContext.xml

   <!-- 註解掃描AOP -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

使用註解aop功能,加入aop1的註解掃描即可。
在這裏插入圖片描述
博客園鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章