首先原文鏈接:https://my.oschina.net/u/2474629/blog/1083448
總結的非常到位,借鑒一下。
首先@Pointcut是把重用的切點表達式抽取出來。
什么是切點表達式?顧名思義,切點表達式就是告訴切面類,通知方法在什么時候運行的 表達式,他能鎖定出一個或者一種方法,或者說鎖定了一個位置出來。
所以,當我們有場景需要抽取出來切點表達式的時候,這種表達式必然是有共性的:被切方法在同一包下、或者被切方法修飾符權限相同(比如所有的public方法)等等。。。
常見的@Pointcut()參數是execution(public int com.xxxx.xx.add(int,*))寫到參數表里匹配任意一個參數:第一個是int類型,第二個任意類型。接下來就借鑒一下別人總結的,注解的參數中多種其他的表達方式構建切點表達式:
execution表達式
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)throws-pattern?)
上面的就是execution表達式的格式,execution匹配的就是連接點(Joinpoint,一般是方法),看上面的表達式execution是固定的,方法的修飾符是可選的,返回類型是必須的,定義的全限類型也是可選的,名稱是必須的,參數是必須的,這些都可以使用通配符。
任何的public方法
execution(public * *(..))
以set開始的方法
execution(* set*(..))
定義在cn.freemethod.business.pack.Say接口中的方法
execution(* cn.freemethod.business.pack.Say.*(..))
任何cn.freemethod.business包中的方法
execution(* cn.freemethod.business.*.*(..))
任何定義在com.xyz.service包或者其子包中的方法
execution(* cn.freemethod.business..*.*(..))
其他表達式
任何在com.xyz.service包中的方法
within(com.xyz.service.*)
任何定義在com.xyz.service包或者其子包中的方法
within(com.xyz.service..*)
任何實現了com.xyz.service.AccountService接口中的方法
this(com.xyz.service.AccountService)
任何目標對象實現了com.xyz.service.AccountService的方法
target(com.xyz.service.AccountService)
一般情況下代理類(Proxy)和目標類(Target)都實現了相同的接口,所以上面的2個基本是等效的。
有且只有一個Serializable參數的方法
args(java.io.Serializable)
只要這個參數實現了java.io.Serializable接口就可以,不管是java.io.Serializable還是Integer,還是String都可以。
目標(target)使用了@Transactional注解的方法
@target(org.springframework.transaction.annotation.Transactional)
目標類(target)如果有Transactional注解中的所有方法
@within(org.springframework.transaction.annotation.Transactional)
任何方法有Transactional注解的方法
@annotation(org.springframework.transaction.annotation.Transactional)
有且僅有一個參數並且參數上類型上有Transactional注解
@args(org.springframework.transaction.annotation.Transactional)
注意是參數類型上有Transactional注解,而不是方法的參數上有注解。
bean的名字為tradeService中的方法
bean(simpleSay)
bean名字為simpleSay中的所有方法。
bean名字能匹配
bean(*Impl)
bean名字匹配*Impl的bean中的所有方法。
