@Aspect通配符
- *:匹配任意字符,只能匹配一個元素
- ..:匹配任意字符,可以匹配多個元素
- +:按類型匹配指定類的所有類,必須在類名後面,繼承或者擴展指定類的所有類,也包括本身
邏輯運算符
- &&(and):與操作,切點的交集
- ||(or):或操作,切點的並集
- !(not):非操作,切點的反集
//匹配com.sunjie包下所有的get方法
@Before("within(com.sunjie.*)"+" && execution(* get(..))")
//匹配所有get方法,但是其類非User類型
@Before("!target(com.sunjie.User)"+" && execution(* get(..))")
//匹配所有User類型或者Teacher類型的類的方法
@Before("target(com.sunjie.User)"+" || target(com.sunjie.Teacher")
@Aspect增強註解
1.@Before
@Before(value=”pointcut()”)
執行方法前調用
2.@AfterReturning
@AfterReturning(value=”pointcut()”,returning=”result”)
執行方法正常返回後調用,異常不調用,
returning成員,可以將目標對象方法的返回值綁定給增強的方法
3.@Around
@Around(value=”pointcut()”)
環繞增強,唯一可以修改方法返回值的註解
4.@AfterThrowing
@AfterReturning(value=”pointcut()”,throwing =”error”)
異常拋出增強
throwing成員,可以將拋出的異常綁定到增強方法中
5.@After
@After(value=”pointcut()”)
方法執行後調用,不管異常還是正常結束,都會調用,一般用於釋放資源。
5.@DeclareParents
@DeclareParents(value=”com.sunjie.User”,defaultImpl=BoySex.Class)
引介增強
@Aspect
public class UserAspect {
@DeclareParents(value="com.sunjie.User",//爲這個類添加接口
defaultImpl=BoySex.class)//默認實現類
public Sex sex; //實現的接口
}
@Aspect切點表達式函數
1.方法切點函數
- execution():方法匹配模式串(支持所有通配符)
表示滿足某一匹配模式的所有目標類方法連接點
execution(<修飾符> <返回類型> <方法名> <參數> <異常>)
修飾符、異常可空
例子
//匹配所有public的方法
execution(public * *(..))
//匹配所有以To結尾的方法
execution(* *To(..))
//匹配所有User類的方法,如果User爲接口,則匹配所有此接口的實現類的此接口方法
execution(* com.sunjie.User.*(..))
//匹配User類型的所有類的方法
execution(* com.sunjie.User+.*(..))
//匹配所有 com.sunjie包下的所有類的所有方法
execution(* com.sunjie.*(..))
//匹配所有 com.sunjie包下以及子包下的所有類的所有方法
execution(* com.sunjie..*(..))
//匹配所有com下的任何包中類名以User結尾,get開頭的方法
execution(* com..*.*User.get*(..))
//匹配所有方法名爲get,第一個參數爲Strng,第二個參數爲int的方法
//java.lang 下的可以直接用類名,其他必須用全限定類名
execution(* get(String,int))
//匹配所有方法名爲get,第一個參數爲Strng,第二個參數爲任意類型的方法
execution(* get(String,*))
//匹配所有方法名爲get,第一個參數爲Strng,後面可以是任意多個參數的任何類型的方法
execution(* get(String,..))
//匹配所有方法名爲get,僅有一個參數,且爲Object的類型或者子類
execution(* get(Object+))
- @annotation():方法註解類名
表示標註了特定註解的目標類方法連接點
//匹配所有標註了@MyAnno註解的方法,進行後置怎強
@AfterReturning("@annotation(com.sunjie.MyAnno)")
public void show(){
System.out.println("hello");
}
2.方法入參切點函數
- args():類名(支持+通配符)
運行入參對象的類型定義連接點
//匹配參數爲Use類型的類或者子類
args(com.sunjie.User)
//區別,只匹配參數爲User類型的類,不包括子類
execution(* *(com.sunjie.User))
- @args():類型註解類名
運行入參對象的類是否標註特定註解定義連接點
3.目標類切點函數
- within():類匹配串(支持所有通配符)
只能是類,接口無任何作用
//匹配User類的所有方法
within(com.sunjie.User)
//匹配com.sunjie包下的所有類的方法,不包括子包
within(com.sunjie.*)
//匹配com.sunjie包下以及子包下的所有類的方法
within(com.sunjie..*)
- target():類名(支持+通配符)
//匹配所有User類型的類的所有方法,包括未在User中定義的方法
target(com.sunjie.User)
- @within():類型註解類名
- @target():類型註解類名
命名切點
public class Cut{
切點命名,只能在本切面類中使用
@Pointcut("within(com.sunjie.User)")
private void cut1();
切點命名,只能在本切面類或者子類中使用
@Pointcut("within(com.sunjie.User)")
protected void cut2();
切點命名,可以在任何類使用
@Pointcut("within(com.sunjie.User)")
public void cut3();
切點命名,複合切點
@Pointcut("cut1() and cut2()")
public void cut4();
}
//其他類引用
@Before("Cut.cut4()")
增強執行順序
- 在同一個切面類中的定義,則按照定義順序來
- 在不同的切面類中定義,且實現了Ordered接口,按照序號順序,越小越先
- 在不同切面類,且沒實現Ordered接口,則不確定
連接點信息
Aspect使用JoinPoint表示連接點對象,環繞增強使用ProceedingJoinPoint,該類是JoinPoint的子類。
JoinPoint方法
- getArgs():獲取入參
- getSignature():獲取方法簽名對象
- getTarget():獲取連接點所在的目標對象
- getThis:獲取代理對象本身
ProceedingJoinPoint方法
除上述方法外,多兩個方法
- proceed():反射執行方法
- proceed(args):使用新參數執行方法
綁定入參
//匹配過程
//通過name,age名稱查詢增強方法中的參數類型,即bind(Integer age,String name)
//發現name爲Sting類型,age爲Integer類型
//所以匹配User類的所有第一個入參爲String類型,第二個是Integer類型的方法
@Before("target(com.sunjie.User) && args(name,age)")
public void bind(Integer age,String name){
}