18、spring-AOP-切點表達式

Spring切點表達式

一、概要

前面定義切點表達式時使用了execution表達式,其實execution就是一個切入點指示符。Spring AOP僅支持部分AspectJ的切入點指示,但基本已經(jīng)滿足我們大部分的需求了,同時Spring AOP還額外支持一個bean切入點指示符。
切面表達式主要由:designators(指示器,匹配java方法),wildcards(通配符),operators(操作運算符)三部分組成

二、指示器

1、說明

主要作用就是通過什么樣的方式來匹配java類的哪些方法

2、分類

按著作用來分主要分為 匹配方法(execution),匹配注解(@within,@target,@args,@annotation),匹配包/類型(within()),匹配對象(target,this),匹配參數(shù)(args)

3、支持的指示器

指示器 描述
execution() 用于匹配方法執(zhí)行的連接點
within() 用于匹配指定的類及其子類中的所有方法
this() 匹配可以向上轉(zhuǎn)型為this指定的類型的代理對象中的所有方法
target() 匹配可以向上轉(zhuǎn)型為target指定的類型的目標對象中的所有方法
args() 用于匹配運行時傳入的參數(shù)列表的類型為指定的參數(shù)列表類型的方法
@within() 用于匹配持有指定注解的類的所有方法
@target() 用于匹配的持有指定注解目標對象的所有方法
@args() 用于匹配運行時 傳入的參數(shù)列表的類型持有 注解列表對應(yīng)的注解的方法
@annotation() 用于匹配持有指定注解的方法
bean bean(Bean的id或名字通配符)匹配特定名稱的Bean對象

三、類型匹配

1、說明

通常用在類型模式的和方法中

2、三種通配符

通配符 說明
* 匹配任何數(shù)量字符
.. 匹配任何數(shù)量字符的重復(fù),如在類型模式中匹配任何數(shù)量子包;而在方法參數(shù)模式中匹配任何數(shù)量參數(shù)
+ 匹配指定類型的子類型;僅能作為后綴放在類型模式后邊

四、操作運算符

1、說明

AspectJ使用 且(&&)、或(||)、非(?。﹣斫M合切入點表達式,由于在xml風格下,由于在XML中使用“&&”需要使用轉(zhuǎn)義字符“&&”來代替之,所以很不方便,因此Spring ASP 提供了and、or、not來代替&&、||、!

2、操作符

操作符 說明
&&或者 and 與操作符
` 或者or` 或操作符
! 或者 not 非操作符

五、execution

1、說明

面粒度最小是達到方法級別,而execution表達式可以用于明確指定方法返回類型,類名,方法名和參數(shù)名等與方法相關(guān)的部件,并且在Spring中,大部分需要使用AOP的業(yè)務(wù)場景也只需要達到方法級別即可,因而execution表達式的使用是最為廣泛的

2、語法格式

execution([方法的可見性] 返回類型 [方法所在類的全路徑名] 方法名(參數(shù)類型列表) [方法拋出的異常類型])

3、栗子

  1. 切面類
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    @Component
    @Aspect
    public class ExecutionAspect {
        @Pointcut("execution(public * com.wener.example.aop.execution.ExecutionService.test())")
        public void execuPoint() {
        }
        @Before("execution(public * com.wener.example.aop.execution.ExecutionService.add(..))")
        public void execuBefore() {
            System.out.println("核心方法之前!!!");
        }
        @Before("execution(public * com.wener.example.aop.execution.ExecutionService.test(..))")
        public void execuAfter() {
            System.out.println("核心方法之后!!!");
        }
    }
    
  2. 目標類
    import org.springframework.stereotype.Service;
    public interface ExecutionService {
        public void test();
        public int add(String name);
    }
    @Service("service")
    public class ExecutionServiceImpl implements ExecutionService {
        @Override
        public void test() {
            System.out.println("測試方法核心代碼!!!");
        }
        @Override
        public int add(String name) {
            System.out.println("添加的方法核心代碼!!!");
            return 0;
        }
    }
    
  3. 測試代碼
      public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-aspect.xml");
            ExecutionService service = context.getBean("service", ExecutionService.class);
            service.add("1111");
            service.test();
        }
    

4、常見表達式

4.1、方法簽名定義切入點

  1. 匹配所有目標類的public方法,第一個為返回類型,第二個為方法名
    execution(public * * (..))execution(* save* (..))
    
  2. 匹配所有目標類以xxx開頭的方法,第一個*代表返回任意類型
    execution(* xxx* (..))
    
  3. 匹配目標類所有以xxx結(jié)尾的方法,并且其方法的參數(shù)表第一個參數(shù)可為任意類型,第二個參數(shù)必須為String
execution(**xxx(*,String))

4.2、類定義切入點

  1. 匹配Service接口及其實現(xiàn)子類中的所有方法
    execution(* com.xxx.Service.*(..))
    

4.3、通過包定義切入點

  1. 匹配service包下的所有類的所有方法,但不包括子包
    execution(* com.xxx.service.*(..))
    
  2. 匹配aop_part包下的所有類的所有方法,包括子包。
    # 注意 (當".."出現(xiàn)再類名中時,后面必須跟" * ",表示包、子孫包下的所有類**)
    execution(* com.xxx.service..*(..))
    
  3. 匹配xxx包及其子包下的所有后綴名為service的類中,所有方法名必須以select為前綴的方法
    execution(* com.xxx..*.*service.select*(..))
    

4.4、方法形參定義切入點

  1. 匹配所有方法名為add,且有兩個參數(shù),其中,第一個的類型為int 第二個參數(shù)是String
    execution(* add(int, String))
    
  2. 匹配所有方法名為add,且至少含有一個參數(shù),并且第一個參數(shù)為int的方法
    execution(* add(int, ..))
    
  3. 匹配所有方法名為add,匹配所有類型的參數(shù)
    execution(* add(int, ..))
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容