最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringAOP中的通知Advice詳解

 更新時(shí)間:2023年08月02日 10:46:23   作者:碼匠_CodeArtist  
這篇文章主要介紹了SpringAOP中的通知Advice詳解,Spring 的 AOP 功能中一個(gè)關(guān)鍵概念是通知Advice與切點(diǎn)Pointcut表達(dá)式相關(guān)聯(lián)在特定節(jié)點(diǎn)織入一些邏輯,Spring 提供了五種類型的通知,需要的朋友可以參考下

一、概述

AOP 中的通知是基于連接點(diǎn)(Join point)業(yè)務(wù)邏輯的一種增強(qiáng),Spring AOP 提供了下面五種通知類型:

  • Before advice(前置通知):連接點(diǎn)前面執(zhí)行,不能終止后續(xù)流程,除非拋異常
  • After returning advice(后置通知):連接點(diǎn)正常返回時(shí)執(zhí)行,有異常不執(zhí)行
  • Around advice(環(huán)繞通知):圍繞連接點(diǎn)前后執(zhí)行,也能捕獲異常處理
  • After advice(最終通知):連接點(diǎn)退出時(shí)執(zhí)行,無(wú)論是正常退出還是異常退出
  • After throwing advice(異常通知):連接點(diǎn)方法拋出異常時(shí)執(zhí)行

AOP 的連接點(diǎn)一般是指目標(biāo)類的方法,五種通知類型執(zhí)行的節(jié)點(diǎn)如下:

在這里插入圖片描述

二、通知的定義

Spring AOP 可以基于 XML 方式和基于注解方式定義,只是寫(xiě)法不同,這里只使用注解的方式來(lái)講解通知的詳細(xì)用法。

1. 前置通知

@Aspect 切面類中使用 @Before 注解簡(jiǎn)單地定義一個(gè)前置通知。

@Aspect
@Component
public class DemoAspect {
    @Before("execution(* cn.codeartist.spring.aop.advice.*.*(..))")
    public void doBefore() {
        // 自定義邏輯
    }
}

2. 后置通知

方法正常返回,會(huì)執(zhí)行后置通知,使用 @AfterReturning 注解定義后置通知。

@AfterReturning("execution(* cn.codeartist.spring.aop.advice.*.*(..))")
public void doAfterReturning() {
    // 自定義邏輯
}

注解的 returning 屬性可以綁定目標(biāo)方法返回值,用于在通知中獲取目標(biāo)方法執(zhí)行完成后的返回結(jié)果。

@AfterReturning(pointcut = "pointcut()", returning = "retVal")
public void doAfterReturning(Object retVal) {
    // 自定義邏輯(通過(guò)參數(shù)綁定方法切入點(diǎn)方法的返回值)
}

當(dāng)注解使用了 returning 屬性時(shí),切入點(diǎn)會(huì)增加返回值類型的限制,上面使用的 Object 類型可以匹配到所有返回值類型的目標(biāo)方法。

例如下面的情況,后置通知的代碼不會(huì)被執(zhí)行:

// 目標(biāo)方法
public String doService() {
    return "碼匠公眾號(hào)";
}
// 后置通知定義
@AfterReturning(pointcut = "pointcut()", returning = "retVal")
public void doAfterReturning(Integer retVal) {
    // 目標(biāo)方法返回值是String類型,結(jié)果參數(shù)綁定類型是Integer,該通知不會(huì)被執(zhí)行
}

3. 環(huán)繞通知

環(huán)繞通知可以在方法執(zhí)行的任何節(jié)點(diǎn)添加邏輯,它可以實(shí)現(xiàn)另外 4 種通知的功能。

如果需要以線程安全的方式在方法執(zhí)行前后共享狀態(tài),可以使用環(huán)繞通知。

@Around 注解來(lái)定義環(huán)繞通知,需要使用 ProceedingJoinPoint 作為參數(shù),來(lái)執(zhí)行目標(biāo)方法調(diào)用。

@Around("execution(* cn.codeartist.spring.aop.advice.*.*(..))")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    // 方法執(zhí)行前邏輯
    Object retVal = joinPoint.proceed();
    // 方法執(zhí)行后邏輯
    return retVal;
}

joinPoint.proceed() 會(huì)調(diào)用目標(biāo)方法,或者是調(diào)用另一個(gè)切面。

雖然環(huán)繞通知可以實(shí)現(xiàn)另外幾種通知的功能,但在使用中都能實(shí)現(xiàn)功能的情況下,優(yōu)先使用其他通知方式。

4. 最終通知

最終通知在方法退出的時(shí)候執(zhí)行,使用 @After 注解定義,最終通知在方法正常退出和拋出異常時(shí)都會(huì)執(zhí)行,通常用于資源的釋放。

@After("execution(* cn.codeartist.spring.aop.advice.*.*(..))")
public void doAfter() {
    // 自定義邏輯
}

5. 異常通知

方法拋出異常的時(shí)候會(huì)執(zhí)行異常通知,使用 @AfterThrowing 定義異常通知。

@AfterThrowing("execution(* cn.codeartist.spring.aop.advice.*.*(..))")
public void doAfterThrowing() {
    // 自定義邏輯
}

注解的 throwing 屬性用來(lái)綁定目標(biāo)方法拋出的異常,用于在通知中獲取目標(biāo)方法拋出的異常實(shí)例。

@AfterThrowing(pointcut = "pointcut()", throwing = "ex")
public void doAfterThrowing(Throwable ex) {
    // 自定義邏輯(通過(guò)參數(shù)綁定方法切入點(diǎn)方法拋出的異常)
}

當(dāng)注解使用了 throwing 屬性時(shí),切入點(diǎn)會(huì)增加異常類型的限制,上面使用的 Throwable 類型可以匹配到所有異常類型。

例如下面的情況,異常通知的代碼不會(huì)被執(zhí)行:

// 目標(biāo)方法
public void doServiceThrow() {
    throw new RuntimeException("Test exception");
}
// 異常通知定義
@AfterThrowing(pointcut = "pointcut()", throwing = "ex")
public void doAfterThrowing(NullPointerException ex) {
    // 目標(biāo)方法拋出的是RuntimeException,參數(shù)綁定類型是NullPointerException,該通知不會(huì)被執(zhí)行
}

三、通知的參數(shù)

在定義通知的方法簽名上可以指定參數(shù)來(lái)綁定目標(biāo)方法的一些信息(例如前面講到的后置通知和異常通知)。

1. 切入點(diǎn)

在定義通知方法的時(shí)候,一般可以使用 JoinPoint 作為參數(shù),環(huán)繞通知使用 ProceedingJoinPoint。常用接口方法如下:

JoinPoint

public interface JoinPoint {
	// 獲取代理對(duì)象
    Object getThis();
    // 獲取目標(biāo)對(duì)象
    Object getTarget();
    // 獲取連接點(diǎn)方法的參數(shù)
    Object[] getArgs();
    // 獲取連接點(diǎn)方法的簽名
    Signature getSignature();
}

ProceedingJoinPoint

public interface ProceedingJoinPoint extends JoinPoint {
    // 執(zhí)行下一個(gè)切面的通知或者目標(biāo)方法
    public Object proceed() throws Throwable;
    // 執(zhí)行下一個(gè)切面的通知或者目標(biāo)方法(帶參數(shù))
    public Object proceed(Object[] args) throws Throwable;
}

切面的切入點(diǎn)一般為方法,所以 Signature 可以轉(zhuǎn)換為 MethodSignature 使用。

2. 通知的參數(shù)傳遞

通知的參數(shù)可以通過(guò)切點(diǎn)表達(dá)式 args 來(lái)指定,具體用法會(huì)在后面切點(diǎn)表達(dá)式詳解中講到。

@Before("pointcut() && args(name,..)")
public void doBefore(String name) {
    // 切點(diǎn)表達(dá)式增加參數(shù)匹配
}

args(name,..) 也會(huì)增加切入點(diǎn)的限制,目標(biāo)方法的參數(shù)個(gè)數(shù)至少為一個(gè),且第一個(gè)參數(shù)類型為 String。

四、通知的順序

Spring AOP 中一個(gè)目標(biāo)類可以被多個(gè)切面切入,多個(gè)切面也可以切入一個(gè)目標(biāo)類。 使用 @Order 注解來(lái)指定切面的優(yōu)先級(jí),來(lái)控制切面的執(zhí)行順序。 在注冊(cè)切面 Bean 的時(shí)候指定 @Order,如下:

@Order(1)
@Aspect
@Component
public class FirstAspect {
    // ......
}

優(yōu)先級(jí)高的切面先執(zhí)行,通知執(zhí)行的順序如下:

在這里插入圖片描述

可以得出:

  • 優(yōu)先級(jí)高的切面,前置通知先執(zhí)行
  • 優(yōu)先級(jí)低的切面,后置通知先執(zhí)行

Order 值越小,優(yōu)先級(jí)越大。

Spring AOP 是基于動(dòng)態(tài)代理的攔截器模式實(shí)現(xiàn)的,切面模型與攔截器模型相似,如下:

在這里插入圖片描述

五、附錄

1. 常用注解

注解描述
@Aspect定義切面類
@Before定義前置通知
@AfterReturning定義后置通知
@Around定義環(huán)繞通知
@After定義最終通知
@AfterThrowing定義異常通知

到此這篇關(guān)于SpringAOP中的通知Advice詳解的文章就介紹到這了,更多相關(guān)SpringAOP的通知內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決JAVA非對(duì)稱加密不同系統(tǒng)加密結(jié)果不一致的問(wèn)題

    解決JAVA非對(duì)稱加密不同系統(tǒng)加密結(jié)果不一致的問(wèn)題

    這篇文章主要介紹了解決JAVA非對(duì)稱加密不同系統(tǒng)加密結(jié)果不一致的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • 關(guān)于Java的二叉樹(shù)、紅黑樹(shù)、B+樹(shù)詳解

    關(guān)于Java的二叉樹(shù)、紅黑樹(shù)、B+樹(shù)詳解

    這篇文章主要介紹了關(guān)于Java的二叉樹(shù)、紅黑樹(shù)、B+樹(shù)詳解,能同時(shí)具備數(shù)組查找快的優(yōu)點(diǎn)以及鏈表插入和刪除快的優(yōu)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)就是樹(shù),需要的朋友可以參考下
    2023-05-05
  • 淺析Java中的訪問(wèn)控制權(quán)限

    淺析Java中的訪問(wèn)控制權(quán)限

    這篇文章主要介紹了淺析Java中的訪問(wèn)控制權(quán)限,在Java中,提供了四種訪問(wèn)權(quán)限控制,分別是默認(rèn)訪問(wèn)權(quán)限、public、private以及protected,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Java中的jinfo命令使用詳解

    Java中的jinfo命令使用詳解

    jinfo是JDK提供的一個(gè)可以實(shí)時(shí)查看Java虛擬機(jī)各種配置參數(shù)和系統(tǒng)屬性的命令行工具,本文給大家介紹下Java中的jinfo命令使用,感興趣的朋友一起看看吧
    2022-03-03
  • 如何在java 8 map中使用stream

    如何在java 8 map中使用stream

    這篇文章主要介紹了如何在java 8 map中使用stream,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring自動(dòng)裝配@Autowired教程

    Spring自動(dòng)裝配@Autowired教程

    @Autowired注解是Spring中非常重要且常見(jiàn)的,接下來(lái)就簡(jiǎn)要的介紹一下它的用法。@Autowired默認(rèn)是通過(guò)set方法,按照類型自動(dòng)裝配JavaBean,set方法可省略不寫(xiě),它主要是修飾在成員變量上
    2023-01-01
  • Spring?Boot?微服務(wù)中集成?MyBatis-Plus?與集成原生?MyBatis在配置上的不同

    Spring?Boot?微服務(wù)中集成?MyBatis-Plus?與集成原生?MyBatis在配置上的不同

    在Spring?Boot微服務(wù)中,MyBatis-Plus通過(guò)其Boot?Starter和豐富的配置屬性,極大的簡(jiǎn)化了MyBatis的集成和配置工作,尤其是對(duì)于全局設(shè)置和常用插件的使用,本文給大家介紹Spring?Boot?微服務(wù)中集成?MyBatis-Plus與集成原生?MyBatis?有哪些配置上的不同,感興趣的朋友一起看看吧
    2025-04-04
  • Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐

    Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐

    本文主要介紹了Springboot+Redis執(zhí)行l(wèi)ua腳本的項(xiàng)目實(shí)踐,詳細(xì)的介紹Redis與Lua腳本的結(jié)合應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • java數(shù)據(jù)結(jié)構(gòu)和算法中數(shù)組的簡(jiǎn)單入門(mén)

    java數(shù)據(jù)結(jié)構(gòu)和算法中數(shù)組的簡(jiǎn)單入門(mén)

    在本文里小編給大家整理了關(guān)于java數(shù)據(jù)結(jié)構(gòu)和算法中數(shù)組的簡(jiǎn)單入門(mén)知識(shí)點(diǎn)整理,需要的朋友們學(xué)習(xí)下。
    2019-06-06
  • java控制臺(tái)版實(shí)現(xiàn)五子棋游戲

    java控制臺(tái)版實(shí)現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了java控制臺(tái)版實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評(píng)論

临西县| 罗甸县| 夏邑县| 明星| 确山县| 稻城县| 富民县| 基隆市| 屯留县| 教育| 楚雄市| 江门市| 郸城县| 方正县| 故城县| 高雄市| 马山县| 津市市| 乐平市| 耿马| 比如县| 高安市| 枣强县| 钟山县| 武平县| 达拉特旗| 大城县| 潞西市| 姜堰市| 什邡市| 大洼县| 五指山市| 博客| 桂阳县| 察雅县| 元江| 饶河县| 双流县| 武山县| 松江区| 新邵县|