一、切入點表達式作用
切入點表達式:通過表達式的方式定位一個或多個具體的連接點。
二、語法細節
1、切入點表達式的語法格式
execution([權限修飾符] [返回值類型] [簡單類名/全類名] [方法名]([參數列表]))
2、通配符
通配符: *: 1)匹配一個或者多個字符:execution(public int com.njf.aop.calc.MyMath*r.*(int, int)) 2)匹配任意一個參數:第一個是int類型,第二個是任意類型(匹配兩個參數) execution(public int com.njf.aop.calc.MyMath*r.*(int, *)) 3)如果 * 放在路徑中,只能匹配一層路徑 4) 權限位置不能使用 * 表示,權限位置不寫就行,public【可選類型】 ..: 1)匹配任意多個參數,任意類型參數 2)匹配任意多層路徑 execution(public int com.njf..calc.MyMath*r.*(..)) 最精確的:execution(public int com.njf.aop.calc.MyMathCalculator.add(int, int)) 最模糊的:execution(* *.*(..))
*星號:
1、匹配一個或者多個字符 (MyMath*r)-->開頭為MyMath,結尾為r
("execution(public int com.achang.inter.impl.MyMath*r.*(int,int))")
2、匹配任意一個參數 *(int,*) --->任意一個方法,第一個參數為int,第二個為任意類型,有且僅有兩個參數
("execution(public int com.achang.inter.impl.MyMathCalculator.*(int,*))")
3、只能匹配一層路徑 com.achang.inter.*.MyMathCalculator --->inter路徑下任意路徑下的MyMathCalculator
("execution(public int com.achang.inter.*.MyMathCalculator.*(int,int))")
4、權限位置*不能:權限位置不寫就行
..點點:
1、匹配任意多個參數,任意類型參數 *(..) --->任意方法任意參數
("execution(public int com.achang.inter.impl.MyMathCalculator.*(..))")
2、匹配任意多層路徑 impl..MyMath --->impl路徑下的任意路徑MyMath
("execution(public int com.achang.inter.impl..MyMath.*(int,int))")
舉例說明:
execution(* com.atguigu.spring.ArithmeticCalculator.*(..)) ArithmeticCalculator接口中聲明的所有方法。 第一個“*”代表任意修飾符及任意返回值。 * 第二個“”代表任意方法。 “…”匹配任意數量、任意類型的參數。 若目標類、接口與該切面類在同一個包中可以省略包名。
3、其他舉例
(1)
表達式:execution (* com.spring.aop.ICalc.* (..))
含義
ICalc 接口中聲明的所有方法
第一個 '*' 代表任意修飾符及任意返回值;
第二個 '*' 代表任意方法;
'..' 匹配任意數量、任意類型的參數;
若目標類、接口與該切面類在同一個包中可以省略包名
(2)
表達式:execution(public * ICalc.*(..) )
含義:Calc 接口的所有公有方法
(3)
表達式:execution(public double ICalc*(..) )
含義:ICalc 接口中返回 double 類型數值的方法
(4)
表達式:execution(public double ICalc.*(double,..))
含義:
第一個參數為 double 類型的方法
'..' 匹配任意數量、任意類型的參數
(5)
表達式:execution(public double ICalc.*(double,double))
含義:參數類型為 double,doule 類型的方法
4、在AspectJ中,切入點表達式可以通過 “&&”、“||”、“!”等操作符結合起來。
表達式:execution(**.add(int,..)) || execution(**.sub(int,..))
含義:任意類中第一個參數為 int 類型的 add 方法或 sub 方法
表達式:!execution(* *.add(int,...))
含義:匹配不是任意類中第一個參數為 int 類型的 add 方法
三、切入點表達式應用到實際的切面類中
四、重用切入點定義
(1)在編寫 AspectJ 切面時,可以直接在通知注解中書寫切入點表達式,但同一個切點表達式可能會在多個通知中重復出現;
(2)在 AspectJ 切面中,可以通過 @PointCut 注解將一個切入點聲明或簡單方法。切入點的方法體通常是空的,因為將切入點定義與應用程序邏輯混在一起是不合理的;
(3)切入點方法的訪問控制符同時也控制着這個切入點的可見性。如果切入點要在多個切面中共用,最好將它們集中在一個公共的類中,在這種情況下,它們必須被聲明為 public,在引入這個切入點時,必須將類名也包括在內。如果類沒有與這個切面放在同一個包中,還必須包含包名。
(4)其他通知可以通過方法名稱引入該切入點;
實現步驟:
1、隨便聲明一個沒有實現的返回void的空方法
2、給方法上標注@Pointcut注解
3、在需要用到這個內容的注解execution屬性內寫入這個空方法的方法名
案例:

代碼示例:
@Pointcut(value="execution(* com.spring.aop.*.*(..))") // 重用的切入點表達式
public void test() {} @Before(value="test()") // 使用前置通知,使用重用的切入點表達式
public void beforeMethod(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs();//獲取方法的參數
String methodName = joinPoint.getSignature().getName();//獲取方法名
System.out.println("method:"+methodName+",arguments:"+Arrays.toString(args)); } @After(value="test()") // 使用前置通知,使用重用的切入點表達式
public void afterMethod() { System.out.println("后置通知"); }