Spring AOP註解

@Aspect通配符

  1. *:匹配任意字符,只能匹配一個元素
  2. ..:匹配任意字符,可以匹配多個元素
  3. +:按類型匹配指定類的所有類,必須在類名後面,繼承或者擴展指定類的所有類,也包括本身

邏輯運算符

  1. &&(and):與操作,切點的交集
  2. ||(or):或操作,切點的並集
  3. !(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(* getObject+))

  • @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()"

增強執行順序

  1. 在同一個切面類中的定義,則按照定義順序來
  2. 在不同的切面類中定義,且實現了Ordered接口,按照序號順序,越小越先
  3. 在不同切面類,且沒實現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){

}
發佈了15 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章