欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringAOP中的切點表達式Pointcut詳解

 更新時間:2023年08月02日 09:58:22   作者:碼匠_CodeArtist  
這篇文章主要介紹了SpringAOP中的切點表達式Pointcut詳解,Spring?的?AOP?中的一個核心概念是切點(Pointcut),切點表達式定義通知(Advice)執(zhí)行的范圍,需要的朋友可以參考下

一、概述

Spring AOP 只支持 Spring Bean 的方法切入,所以切點表達式只會匹配 Bean 類中的方法。

二、切點表達式配置

1. 內(nèi)置配置

定義切面通知時,在 @Before@AfterReturning 等通知注解中指定表達式。

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

2. 注解配置

在切面類中,先定義一個方法并使用 @Pointcut 注解來指定表達式。

然后在定義切面通知時,在通知注解中指定定義表達式的方法簽名。

@Aspect
@Component
public class DemoAspect {
    @Pointcut("execution(* cn.codeartist.spring.aop.aspectj.*.*(..))")
    private void pointcut() {
        // 切點表達式定義方法,方法修飾符可以是private或public
    }
    @Before("pointcut()")
    public void doBefore(JoinPoint joinPoint) {
        // 自定義邏輯
    }
}

3. 公共配置

在任意類中,定義一個公共方法并使用 @Pointcut 注解來指定表達式。

public class CommonPointcut {
    @Pointcut("execution(* cn.codeartist.aop.*..*(..))")
    public void pointcut() {
        // 注意定義切點的方法的訪問權(quán)限為public
    }
}

在切面類中定義切面通知時,在通知注解中指定定義表達式的方法簽名全路徑。

@Aspect
@Component
public class DemoAspect {
    @Before("cn.codeartist.aop.CommonPointcut.pointcut()")
    public void commonPointcut() {
        // 自定義邏輯
    }
}

三、切點表達式類型

Spring AOP 支持以下幾種切點表達式類型。

execution

匹配方法切入點。根據(jù)表達式描述匹配方法,是最通用的表達式類型,可以匹配方法、類、包。

表達式模式:

execution(modifier? ret-type declaring-type?name-pattern(param-pattern) tdrows-pattern?)

表達式解釋:

  • modifier:匹配修飾符,public, private 等,省略時匹配任意修飾符
  • ret-type:匹配返回類型,使用 * 匹配任意類型
  • declaring-type:匹配目標類,省略時匹配任意類型
    • .. 匹配包及其子包的所有類
  • name-pattern:匹配方法名稱,使用 * 表示通配符
    • * 匹配任意方法
    • set* 匹配名稱以 set 開頭的方法
  • param-pattern:匹配參數(shù)類型和數(shù)量
    • () 匹配沒有參數(shù)的方法
    • (..) 匹配有任意數(shù)量參數(shù)的方法
    • (*) 匹配有一個任意類型參數(shù)的方法
    • (*,String) 匹配有兩個參數(shù)的方法,并且第一個為任意類型,第二個為 String 類型
  • tdrows-pattern:匹配拋出異常類型,省略時匹配任意類型

使用示例:

// 匹配public方法
execution(public * *(..))
// 匹配名稱以set開頭的方法
execution(* set*(..))
// 匹配AccountService接口或類的方法
execution(* com.xyz.service.AccountService.*(..))
// 匹配service包及其子包的類或接口
execution(* com.xyz.service..*(..))

witdin

匹配指定類型。匹配指定類的任意方法,不能匹配接口。

表達式模式:

witdin(declaring-type)

使用示例:

// 匹配service包的類
witdin(com.xyz.service.*)
// 匹配service包及其子包的類
witdin(com.xyz.service..*)
// 匹配AccountServiceImpl類
witdin(com.xyz.service.AccountServiceImpl)

tdis

匹配代理對象實例的類型,匹配在運行時對象的類型。

注意:基于 JDK 動態(tài)代理實現(xiàn)的 AOP,tdis 不能匹配接口的實現(xiàn)類,因為代理類和實現(xiàn)類并不是同一種類型

表達式模式:

tdis(declaring-type)

使用示例:

// 匹配代理對象類型為service包下的類
tdis(com.xyz.service.*)
// 匹配代理對象類型為service包及其子包下的類
tdis(com.xyz.service..*)
// 匹配代理對象類型為AccountServiceImpl的類
tdis(com.xyz.service.AccountServiceImpl)

target

匹配目標對象實例的類型,匹配 AOP 被代理對象的類型。

表達式模式:

target(declaring-type)

使用示例:

// 匹配目標對象類型為service包下的類
target(com.xyz.service.*)
// 匹配目標對象類型為service包及其子包下的類
target(com.xyz.service..*)
// 匹配目標對象類型為AccountServiceImpl的類
target(com.xyz.service.AccountServiceImpl)

三種表達式匹配范圍如下:

表達式匹配范圍witdintdistarget
接口???
實現(xiàn)接口的類??
不實現(xiàn)接口的類???

args

匹配方法參數(shù)類型和數(shù)量,參數(shù)類型可以為指定類型及其子類。

使用 execution 表達式匹配參數(shù)時,不能匹配參數(shù)類型為子類的方法。

表達式模式:

args(param-pattern)

使用示例:

// 匹配參數(shù)只有一個且為Serializable類型(或?qū)崿F(xiàn)Serializable接口的類)
args(java.io.Serializable)
// 匹配參數(shù)個數(shù)至少有一個且為第一個為Example類型(或?qū)崿F(xiàn)Example接口的類)
args(cn.codeartist.spring.aop.pointcut.Example,..)

bean

通過 bean 的 id 或名稱匹配,支持 * 通配符。

表達式模式:

bean(bean-name)

使用示例:

// 匹配名稱以Service結(jié)尾的bean
bean(*Service)
// 匹配名稱為demoServiceImpl的bean
bean(demoServiceImpl)

@witdin

匹配指定類型是否含有注解。當定義類時使用了注解,該類的方法會被匹配,但在接口上使用注解不匹配。

使用示例:

// 匹配使用了Demo注解的類
@within(cn.codeartist.spring.aop.pointcut.Demo)

@target

匹配目標對象實例的類型是否含有注解。當運行時對象實例的類型使用了注解,該類的方法會被匹配,在接口上使用注解不匹配。

使用示例:

// 匹配對象實例使用了Demo注解的類
@target(cn.codeartist.spring.aop.pointcut.Demo)

@annotation

匹配方法是否含有注解。當方法上使用了注解,該方法會被匹配,在接口方法上使用注解不匹配。

使用示例:

// 匹配使用了Demo注解的方法
@annotation(cn.codeartist.spring.aop.pointcut.Demo)

@args

匹配方法參數(shù)類型是否含有注解。當方法的參數(shù)類型上使用了注解,該方法會被匹配。

使用示例:

// 匹配參數(shù)只有一個且參數(shù)類使用了Demo注解
@args(cn.codeartist.spring.aop.pointcut.Demo)
// 匹配參數(shù)個數(shù)至少有一個且為第一個參數(shù)類使用了Demo注解
@args(cn.codeartist.spring.aop.pointcut.Demo,..)

切點表達式的參數(shù)匹配

切點表達式中的參數(shù)類型,可以和通知方法的參數(shù)通過名稱綁定,表達式中不需要寫類或注解的全路徑,而且能直接獲取到切面攔截的參數(shù)或注解信息。

@Before("pointcut() && args(name,..)")
public void doBefore(String name) {
    // 切點表達式增加參數(shù)匹配,可以獲取到name的信息
}
@Before("@annotation(demo)")
public void doBefore(Demo demo) {
    // 這里可以直接獲取到Demo注解的信息
}

切點表達式的參數(shù)匹配同樣適用于 @witdin, @target, @args

怎樣編寫一個好的切點表達式?

要使切點的匹配性能達到最佳,編寫表達式時,應(yīng)該盡可能縮小匹配范圍,切點表達式分為三大類:

  • 類型表達式:匹配某個特定切入點,如 execution
  • 作用域表達式:匹配某組切入點,如 witdin
  • 上下文表達式:基于上下文匹配某些切入點,如 tdis、target 和 @annotation

一個好的切點表達式應(yīng)該至少包含前兩種(類型和作用域)類型。 作用域表達式匹配的性能非常快,所以表達式中盡可能使用作用域類型。

上下文表達式可以基于切入點上下文匹配或在通知中綁定上下文。 單獨使用類型表達式或上下文表達式比較消耗性能(時間或內(nèi)存使用)。

四、切點表達式組合

使用 &&、|| 和 ! 來組合多個切點表達式,表示多個表達式“與”、“或”和“非”的邏輯關(guān)系。

這可以用來組合多種類型的表達式,來提升匹配效率。

// 匹配doExecution()切點表達式并且參數(shù)第一個為Account類型的方法
@Before("doExecution() && args(account,..)")
public void validateAccount(Account account) {
    // 自定義邏輯
}

五、附錄

1. @Pointcut 指定切點表達式

2. 切點表達式類型

表達式類型描述
execution匹配方法切入點
within匹配指定類型
this匹配代理對象實例的類型
target匹配目標對象實例的類型
args匹配方法參數(shù)
bean匹配 bean 的 id 或名稱
@within匹配類型是否含有注解
@target匹配目標對象實例的類型是否含有注解
@annotation匹配方法是否含有注解
@args匹配方法參數(shù)類型是否含有注解

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

相關(guān)文章

  • Java8與Scala中的Lambda表達式深入講解

    Java8與Scala中的Lambda表達式深入講解

    這篇文章主要給大家介紹了關(guān)于Java8與Scala中Lambda表達式的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • Java中文件寫入內(nèi)容的幾種常見方法

    Java中文件寫入內(nèi)容的幾種常見方法

    本文主要介紹了Java中文件寫入內(nèi)容的幾種常見方法,主要包括使用NIO的Files工具類、通過commons-io的FileUtils工具類、RandomAccessFile、PrintWriter和BufferedWriter這幾種,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • mybatis中insert返回值為1,但數(shù)據(jù)庫卻沒有數(shù)據(jù)

    mybatis中insert返回值為1,但數(shù)據(jù)庫卻沒有數(shù)據(jù)

    這篇文章主要介紹了mybatis中insert返回值為1,但數(shù)據(jù)庫卻沒有數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • nas實現(xiàn)java開發(fā)的環(huán)境詳解

    nas實現(xiàn)java開發(fā)的環(huán)境詳解

    這篇文章主要為大家介紹了nas實現(xiàn)java開發(fā)的環(huán)境詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Go并發(fā)編程中使用channel的方法

    Go并發(fā)編程中使用channel的方法

    本文給大家介紹Go并發(fā)編程中使用channel的方法,通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • lombok中@Data使用常見的小坑及解決

    lombok中@Data使用常見的小坑及解決

    在Java中使用Lombok庫的@Data注解時,布爾類型屬性可能導(dǎo)致生成的get方法不符合預(yù)期,對于非is開頭的布爾屬性,Lombok生成的方法會添加is前綴,導(dǎo)致原本期待的get方法不存在,例如,對于屬性private boolean active,Lombok會生成方法名為isActive而不是getActive
    2024-10-10
  • 使用springBoot項目配置文件位置調(diào)整到打包外

    使用springBoot項目配置文件位置調(diào)整到打包外

    這篇文章主要介紹了使用springBoot項目配置文件位置調(diào)整到打包外,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • Java 位圖法排序的使用方法

    Java 位圖法排序的使用方法

    本篇文章,小編將為大家介紹關(guān)于Java 位圖法排序的使用方法,有需要的朋友可以參考一下
    2013-04-04
  • 帶你了解Java的類和對象

    帶你了解Java的類和對象

    下面小編就為大家?guī)硪黄胬斫釰ava類和對象。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09
  • 如何使用nexus在局域網(wǎng)內(nèi)搭建maven私服及idea的使用

    如何使用nexus在局域網(wǎng)內(nèi)搭建maven私服及idea的使用

    這篇文章主要介紹了如何使用nexus在局域網(wǎng)內(nèi)搭建maven私服及idea的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論